Merge branch 'release/1.0'

This commit is contained in:
Victor Bodinaud
2024-04-18 19:33:09 +02:00
69 changed files with 2727 additions and 29 deletions

View File

@@ -8,17 +8,113 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
524FA6002BCACDCE00133747 /* AlloVictorApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA5FF2BCACDCE00133747 /* AlloVictorApp.swift */; }; 524FA6002BCACDCE00133747 /* AlloVictorApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA5FF2BCACDCE00133747 /* AlloVictorApp.swift */; };
524FA6022BCACDCE00133747 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6012BCACDCE00133747 /* ContentView.swift */; }; 524FA6022BCACDCE00133747 /* OffersListScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6012BCACDCE00133747 /* OffersListScreen.swift */; };
524FA6042BCACDCF00133747 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6032BCACDCF00133747 /* Assets.xcassets */; }; 524FA6042BCACDCF00133747 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6032BCACDCF00133747 /* Assets.xcassets */; };
524FA6072BCACDCF00133747 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6062BCACDCF00133747 /* Preview Assets.xcassets */; }; 524FA6072BCACDCF00133747 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6062BCACDCF00133747 /* Preview Assets.xcassets */; };
524FA60F2BCACF0500133747 /* Screen1.json in Resources */ = {isa = PBXBuildFile; fileRef = 524FA60E2BCACF0500133747 /* Screen1.json */; };
524FA6112BCACF3A00133747 /* Screen2.json in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6102BCACF3A00133747 /* Screen2.json */; };
524FA61B2BCAD04B00133747 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA61A2BCAD04B00133747 /* Constants.swift */; };
524FA61D2BCAD0F100133747 /* OfferListResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA61C2BCAD0F100133747 /* OfferListResponseDTO.swift */; };
524FA61F2BCAD0FD00133747 /* OfferDetailsResponseDTO.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA61E2BCAD0FD00133747 /* OfferDetailsResponseDTO.swift */; };
524FA6212BCAD22D00133747 /* HTTPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6202BCAD22D00133747 /* HTTPClient.swift */; };
524FA6232BCAD29000133747 /* AlloVictorViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6222BCAD29000133747 /* AlloVictorViewModel.swift */; };
524FA6252BCAD58400133747 /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6242BCAD58400133747 /* AppState.swift */; };
524FA6272BCAE1C500133747 /* OfferListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6262BCAE1C500133747 /* OfferListView.swift */; };
524FA62A2BCAEC0B00133747 /* CachedAsyncImage in Frameworks */ = {isa = PBXBuildFile; productRef = 524FA6292BCAEC0B00133747 /* CachedAsyncImage */; };
524FA62C2BCAF2CF00133747 /* AlloFlashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA62B2BCAF2CF00133747 /* AlloFlashView.swift */; };
524FA63D2BCBF4C300133747 /* tt_chocolates_light.otf in Resources */ = {isa = PBXBuildFile; fileRef = 524FA62F2BCBF4C300133747 /* tt_chocolates_light.otf */; };
524FA63E2BCBF4C300133747 /* tt_chocolates_extralight.otf in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6302BCBF4C300133747 /* tt_chocolates_extralight.otf */; };
524FA63F2BCBF4C300133747 /* tt_chocolates_regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6312BCBF4C300133747 /* tt_chocolates_regular.otf */; };
524FA6412BCBF4C300133747 /* tt_chocolates_demibold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6332BCBF4C300133747 /* tt_chocolates_demibold.otf */; };
524FA6442BCBF4C300133747 /* tt_chocolates_extrabold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6362BCBF4C300133747 /* tt_chocolates_extrabold.otf */; };
524FA6452BCBF4C300133747 /* tt_chocolates_bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = 524FA6372BCBF4C300133747 /* tt_chocolates_bold.otf */; };
524FA6492BCBF4C300133747 /* tt_chocolates_medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = 524FA63B2BCBF4C300133747 /* tt_chocolates_medium.otf */; };
524FA64D2BCBFA3000133747 /* TextModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA64C2BCBFA3000133747 /* TextModifier.swift */; };
524FA64F2BCC0AA100133747 /* OfferDetailsScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA64E2BCC0AA100133747 /* OfferDetailsScreen.swift */; };
524FA6512BCC115B00133747 /* OffererUserView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6502BCC115B00133747 /* OffererUserView.swift */; };
524FA6532BCC326500133747 /* ShareView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6522BCC326500133747 /* ShareView.swift */; };
524FA6552BCC339A00133747 /* OfferDetailsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6542BCC339A00133747 /* OfferDetailsView.swift */; };
524FA6572BCC34E900133747 /* OfferSocialView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 524FA6562BCC34E800133747 /* OfferSocialView.swift */; };
525ED7342BCD257C00FE6109 /* AvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525ED7332BCD257C00FE6109 /* AvatarView.swift */; };
52B222022BD1492600B55575 /* ShowFullPictureScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222012BD1492600B55575 /* ShowFullPictureScreen.swift */; };
52B222112BD1631600B55575 /* NotFoundScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222102BD1631600B55575 /* NotFoundScreen.swift */; };
52B222132BD16DC800B55575 /* OfferDetailsBodyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222122BD16DC800B55575 /* OfferDetailsBodyView.swift */; };
52B222172BD1737500B55575 /* Extension+View.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222162BD1737500B55575 /* Extension+View.swift */; };
52B222192BD173FF00B55575 /* OffererUserRatingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222182BD173FF00B55575 /* OffererUserRatingView.swift */; };
52B2221B2BD1749E00B55575 /* OffererUserInfos.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2221A2BD1749E00B55575 /* OffererUserInfos.swift */; };
52B2221D2BD1756100B55575 /* OffererUserProStatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2221C2BD1756100B55575 /* OffererUserProStatusView.swift */; };
52B2221F2BD175E300B55575 /* OffererUserGallery.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2221E2BD175E300B55575 /* OffererUserGallery.swift */; };
52B222232BD1782700B55575 /* OfferHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222222BD1782700B55575 /* OfferHeaderView.swift */; };
52B222252BD178D000B55575 /* OfferBodyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222242BD178D000B55575 /* OfferBodyView.swift */; };
52B222292BD17A6300B55575 /* Offer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222282BD17A6300B55575 /* Offer.swift */; };
52B2222B2BD17A7F00B55575 /* Relationships.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2222A2BD17A7F00B55575 /* Relationships.swift */; };
52B2222D2BD17A9100B55575 /* Leaseholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2222C2BD17A9100B55575 /* Leaseholder.swift */; };
52B2222F2BD17AA100B55575 /* Social.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2222E2BD17AA100B55575 /* Social.swift */; };
52B222312BD17ACB00B55575 /* OfferPicture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222302BD17ACB00B55575 /* OfferPicture.swift */; };
52B222332BD17ADC00B55575 /* OfferPictureUrls.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222322BD17ADC00B55575 /* OfferPictureUrls.swift */; };
52B222352BD17AEB00B55575 /* OfferersUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222342BD17AEB00B55575 /* OfferersUser.swift */; };
52B222372BD17B0100B55575 /* OfferersUserMeta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222362BD17B0100B55575 /* OfferersUserMeta.swift */; };
52B222392BD17B1200B55575 /* GalleryPicture.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222382BD17B1200B55575 /* GalleryPicture.swift */; };
52B2223B2BD17BD100B55575 /* OfferDetailsAwnserCountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2223A2BD17BD100B55575 /* OfferDetailsAwnserCountView.swift */; };
52B2223F2BD17D5800B55575 /* OfferDetailsGalleryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B2223E2BD17D5800B55575 /* OfferDetailsGalleryView.swift */; };
52B222412BD17DF100B55575 /* OfferDetailsLeaseholderInfosView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222402BD17DF100B55575 /* OfferDetailsLeaseholderInfosView.swift */; };
52B222432BD1864100B55575 /* OfferDetailsMapView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 52B222422BD1864100B55575 /* OfferDetailsMapView.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
524FA5FC2BCACDCE00133747 /* AlloVictor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AlloVictor.app; sourceTree = BUILT_PRODUCTS_DIR; }; 524FA5FC2BCACDCE00133747 /* AlloVictor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AlloVictor.app; sourceTree = BUILT_PRODUCTS_DIR; };
524FA5FF2BCACDCE00133747 /* AlloVictorApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlloVictorApp.swift; sourceTree = "<group>"; }; 524FA5FF2BCACDCE00133747 /* AlloVictorApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlloVictorApp.swift; sourceTree = "<group>"; };
524FA6012BCACDCE00133747 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; }; 524FA6012BCACDCE00133747 /* OffersListScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OffersListScreen.swift; sourceTree = "<group>"; };
524FA6032BCACDCF00133747 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; }; 524FA6032BCACDCF00133747 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
524FA6062BCACDCF00133747 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; }; 524FA6062BCACDCF00133747 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
524FA60E2BCACF0500133747 /* Screen1.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Screen1.json; sourceTree = "<group>"; };
524FA6102BCACF3A00133747 /* Screen2.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = Screen2.json; sourceTree = "<group>"; };
524FA61A2BCAD04B00133747 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
524FA61C2BCAD0F100133747 /* OfferListResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferListResponseDTO.swift; sourceTree = "<group>"; };
524FA61E2BCAD0FD00133747 /* OfferDetailsResponseDTO.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsResponseDTO.swift; sourceTree = "<group>"; };
524FA6202BCAD22D00133747 /* HTTPClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPClient.swift; sourceTree = "<group>"; };
524FA6222BCAD29000133747 /* AlloVictorViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlloVictorViewModel.swift; sourceTree = "<group>"; };
524FA6242BCAD58400133747 /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
524FA6262BCAE1C500133747 /* OfferListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferListView.swift; sourceTree = "<group>"; };
524FA62B2BCAF2CF00133747 /* AlloFlashView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlloFlashView.swift; sourceTree = "<group>"; };
524FA62F2BCBF4C300133747 /* tt_chocolates_light.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = tt_chocolates_light.otf; sourceTree = "<group>"; };
524FA6302BCBF4C300133747 /* tt_chocolates_extralight.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = tt_chocolates_extralight.otf; sourceTree = "<group>"; };
524FA6312BCBF4C300133747 /* tt_chocolates_regular.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = tt_chocolates_regular.otf; sourceTree = "<group>"; };
524FA6332BCBF4C300133747 /* tt_chocolates_demibold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = tt_chocolates_demibold.otf; sourceTree = "<group>"; };
524FA6362BCBF4C300133747 /* tt_chocolates_extrabold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = tt_chocolates_extrabold.otf; sourceTree = "<group>"; };
524FA6372BCBF4C300133747 /* tt_chocolates_bold.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = tt_chocolates_bold.otf; sourceTree = "<group>"; };
524FA63B2BCBF4C300133747 /* tt_chocolates_medium.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = tt_chocolates_medium.otf; sourceTree = "<group>"; };
524FA64A2BCBF78200133747 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
524FA64C2BCBFA3000133747 /* TextModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextModifier.swift; sourceTree = "<group>"; };
524FA64E2BCC0AA100133747 /* OfferDetailsScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsScreen.swift; sourceTree = "<group>"; };
524FA6502BCC115B00133747 /* OffererUserView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OffererUserView.swift; sourceTree = "<group>"; };
524FA6522BCC326500133747 /* ShareView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareView.swift; sourceTree = "<group>"; };
524FA6542BCC339A00133747 /* OfferDetailsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsView.swift; sourceTree = "<group>"; };
524FA6562BCC34E800133747 /* OfferSocialView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferSocialView.swift; sourceTree = "<group>"; };
525ED7332BCD257C00FE6109 /* AvatarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AvatarView.swift; sourceTree = "<group>"; };
52B222012BD1492600B55575 /* ShowFullPictureScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowFullPictureScreen.swift; sourceTree = "<group>"; };
52B222102BD1631600B55575 /* NotFoundScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotFoundScreen.swift; sourceTree = "<group>"; };
52B222122BD16DC800B55575 /* OfferDetailsBodyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsBodyView.swift; sourceTree = "<group>"; };
52B222162BD1737500B55575 /* Extension+View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Extension+View.swift"; sourceTree = "<group>"; };
52B222182BD173FF00B55575 /* OffererUserRatingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OffererUserRatingView.swift; sourceTree = "<group>"; };
52B2221A2BD1749E00B55575 /* OffererUserInfos.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OffererUserInfos.swift; sourceTree = "<group>"; };
52B2221C2BD1756100B55575 /* OffererUserProStatusView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OffererUserProStatusView.swift; sourceTree = "<group>"; };
52B2221E2BD175E300B55575 /* OffererUserGallery.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OffererUserGallery.swift; sourceTree = "<group>"; };
52B222222BD1782700B55575 /* OfferHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferHeaderView.swift; sourceTree = "<group>"; };
52B222242BD178D000B55575 /* OfferBodyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferBodyView.swift; sourceTree = "<group>"; };
52B222282BD17A6300B55575 /* Offer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Offer.swift; sourceTree = "<group>"; };
52B2222A2BD17A7F00B55575 /* Relationships.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Relationships.swift; sourceTree = "<group>"; };
52B2222C2BD17A9100B55575 /* Leaseholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Leaseholder.swift; sourceTree = "<group>"; };
52B2222E2BD17AA100B55575 /* Social.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Social.swift; sourceTree = "<group>"; };
52B222302BD17ACB00B55575 /* OfferPicture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferPicture.swift; sourceTree = "<group>"; };
52B222322BD17ADC00B55575 /* OfferPictureUrls.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferPictureUrls.swift; sourceTree = "<group>"; };
52B222342BD17AEB00B55575 /* OfferersUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferersUser.swift; sourceTree = "<group>"; };
52B222362BD17B0100B55575 /* OfferersUserMeta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferersUserMeta.swift; sourceTree = "<group>"; };
52B222382BD17B1200B55575 /* GalleryPicture.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GalleryPicture.swift; sourceTree = "<group>"; };
52B2223A2BD17BD100B55575 /* OfferDetailsAwnserCountView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsAwnserCountView.swift; sourceTree = "<group>"; };
52B2223E2BD17D5800B55575 /* OfferDetailsGalleryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsGalleryView.swift; sourceTree = "<group>"; };
52B222402BD17DF100B55575 /* OfferDetailsLeaseholderInfosView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsLeaseholderInfosView.swift; sourceTree = "<group>"; };
52B222422BD1864100B55575 /* OfferDetailsMapView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OfferDetailsMapView.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@@ -26,6 +122,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
524FA62A2BCAEC0B00133747 /* CachedAsyncImage in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -51,8 +148,17 @@
524FA5FE2BCACDCE00133747 /* AlloVictor */ = { 524FA5FE2BCACDCE00133747 /* AlloVictor */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
524FA64A2BCBF78200133747 /* Info.plist */,
52B222152BD1735F00B55575 /* Extensions */,
52B222272BD17A5000B55575 /* Models */,
524FA6192BCAD03600133747 /* DTO */,
524FA6182BCAD02E00133747 /* Screens */,
524FA6172BCAD02600133747 /* Utils */,
524FA6162BCAD01E00133747 /* Views */,
524FA6152BCAD01700133747 /* ViewModels */,
524FA60D2BCACE9400133747 /* Resources */,
524FA6242BCAD58400133747 /* AppState.swift */,
524FA5FF2BCACDCE00133747 /* AlloVictorApp.swift */, 524FA5FF2BCACDCE00133747 /* AlloVictorApp.swift */,
524FA6012BCACDCE00133747 /* ContentView.swift */,
524FA6032BCACDCF00133747 /* Assets.xcassets */, 524FA6032BCACDCF00133747 /* Assets.xcassets */,
524FA6052BCACDCF00133747 /* Preview Content */, 524FA6052BCACDCF00133747 /* Preview Content */,
); );
@@ -67,6 +173,157 @@
path = "Preview Content"; path = "Preview Content";
sourceTree = "<group>"; sourceTree = "<group>";
}; };
524FA60D2BCACE9400133747 /* Resources */ = {
isa = PBXGroup;
children = (
524FA62D2BCBF4AD00133747 /* Fonts */,
524FA60E2BCACF0500133747 /* Screen1.json */,
524FA6102BCACF3A00133747 /* Screen2.json */,
);
path = Resources;
sourceTree = "<group>";
};
524FA6152BCAD01700133747 /* ViewModels */ = {
isa = PBXGroup;
children = (
524FA6222BCAD29000133747 /* AlloVictorViewModel.swift */,
);
path = ViewModels;
sourceTree = "<group>";
};
524FA6162BCAD01E00133747 /* Views */ = {
isa = PBXGroup;
children = (
52B222142BD16E5200B55575 /* Components */,
524FA64B2BCBFA1900133747 /* Modifiers */,
524FA62B2BCAF2CF00133747 /* AlloFlashView.swift */,
524FA6262BCAE1C500133747 /* OfferListView.swift */,
524FA6542BCC339A00133747 /* OfferDetailsView.swift */,
524FA6502BCC115B00133747 /* OffererUserView.swift */,
);
path = Views;
sourceTree = "<group>";
};
524FA6172BCAD02600133747 /* Utils */ = {
isa = PBXGroup;
children = (
524FA61A2BCAD04B00133747 /* Constants.swift */,
524FA6202BCAD22D00133747 /* HTTPClient.swift */,
);
path = Utils;
sourceTree = "<group>";
};
524FA6182BCAD02E00133747 /* Screens */ = {
isa = PBXGroup;
children = (
52B222102BD1631600B55575 /* NotFoundScreen.swift */,
524FA64E2BCC0AA100133747 /* OfferDetailsScreen.swift */,
524FA6012BCACDCE00133747 /* OffersListScreen.swift */,
52B222012BD1492600B55575 /* ShowFullPictureScreen.swift */,
);
path = Screens;
sourceTree = "<group>";
};
524FA6192BCAD03600133747 /* DTO */ = {
isa = PBXGroup;
children = (
524FA61E2BCAD0FD00133747 /* OfferDetailsResponseDTO.swift */,
524FA61C2BCAD0F100133747 /* OfferListResponseDTO.swift */,
);
path = DTO;
sourceTree = "<group>";
};
524FA62D2BCBF4AD00133747 /* Fonts */ = {
isa = PBXGroup;
children = (
524FA6372BCBF4C300133747 /* tt_chocolates_bold.otf */,
524FA6332BCBF4C300133747 /* tt_chocolates_demibold.otf */,
524FA6362BCBF4C300133747 /* tt_chocolates_extrabold.otf */,
524FA6302BCBF4C300133747 /* tt_chocolates_extralight.otf */,
524FA62F2BCBF4C300133747 /* tt_chocolates_light.otf */,
524FA63B2BCBF4C300133747 /* tt_chocolates_medium.otf */,
524FA6312BCBF4C300133747 /* tt_chocolates_regular.otf */,
);
path = Fonts;
sourceTree = "<group>";
};
524FA64B2BCBFA1900133747 /* Modifiers */ = {
isa = PBXGroup;
children = (
524FA64C2BCBFA3000133747 /* TextModifier.swift */,
);
path = Modifiers;
sourceTree = "<group>";
};
52B222142BD16E5200B55575 /* Components */ = {
isa = PBXGroup;
children = (
52B222212BD1780F00B55575 /* Offer */,
52B222262BD17A1A00B55575 /* OfferDetails */,
52B222202BD1766E00B55575 /* OffererUser */,
525ED7332BCD257C00FE6109 /* AvatarView.swift */,
524FA6522BCC326500133747 /* ShareView.swift */,
);
path = Components;
sourceTree = "<group>";
};
52B222152BD1735F00B55575 /* Extensions */ = {
isa = PBXGroup;
children = (
52B222162BD1737500B55575 /* Extension+View.swift */,
);
path = Extensions;
sourceTree = "<group>";
};
52B222202BD1766E00B55575 /* OffererUser */ = {
isa = PBXGroup;
children = (
52B2221E2BD175E300B55575 /* OffererUserGallery.swift */,
52B2221A2BD1749E00B55575 /* OffererUserInfos.swift */,
52B2221C2BD1756100B55575 /* OffererUserProStatusView.swift */,
52B222182BD173FF00B55575 /* OffererUserRatingView.swift */,
);
path = OffererUser;
sourceTree = "<group>";
};
52B222212BD1780F00B55575 /* Offer */ = {
isa = PBXGroup;
children = (
52B222242BD178D000B55575 /* OfferBodyView.swift */,
52B222222BD1782700B55575 /* OfferHeaderView.swift */,
524FA6562BCC34E800133747 /* OfferSocialView.swift */,
);
path = Offer;
sourceTree = "<group>";
};
52B222262BD17A1A00B55575 /* OfferDetails */ = {
isa = PBXGroup;
children = (
52B222122BD16DC800B55575 /* OfferDetailsBodyView.swift */,
52B2223A2BD17BD100B55575 /* OfferDetailsAwnserCountView.swift */,
52B2223E2BD17D5800B55575 /* OfferDetailsGalleryView.swift */,
52B222402BD17DF100B55575 /* OfferDetailsLeaseholderInfosView.swift */,
52B222422BD1864100B55575 /* OfferDetailsMapView.swift */,
);
path = OfferDetails;
sourceTree = "<group>";
};
52B222272BD17A5000B55575 /* Models */ = {
isa = PBXGroup;
children = (
52B222382BD17B1200B55575 /* GalleryPicture.swift */,
52B2222C2BD17A9100B55575 /* Leaseholder.swift */,
52B222282BD17A6300B55575 /* Offer.swift */,
52B222342BD17AEB00B55575 /* OfferersUser.swift */,
52B222362BD17B0100B55575 /* OfferersUserMeta.swift */,
52B222302BD17ACB00B55575 /* OfferPicture.swift */,
52B222322BD17ADC00B55575 /* OfferPictureUrls.swift */,
52B2222A2BD17A7F00B55575 /* Relationships.swift */,
52B2222E2BD17AA100B55575 /* Social.swift */,
);
path = Models;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@@ -83,6 +340,9 @@
dependencies = ( dependencies = (
); );
name = AlloVictor; name = AlloVictor;
packageProductDependencies = (
524FA6292BCAEC0B00133747 /* CachedAsyncImage */,
);
productName = AlloVictor; productName = AlloVictor;
productReference = 524FA5FC2BCACDCE00133747 /* AlloVictor.app */; productReference = 524FA5FC2BCACDCE00133747 /* AlloVictor.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
@@ -111,6 +371,9 @@
Base, Base,
); );
mainGroup = 524FA5F32BCACDCE00133747; mainGroup = 524FA5F32BCACDCE00133747;
packageReferences = (
524FA6282BCAEC0B00133747 /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */,
);
productRefGroup = 524FA5FD2BCACDCE00133747 /* Products */; productRefGroup = 524FA5FD2BCACDCE00133747 /* Products */;
projectDirPath = ""; projectDirPath = "";
projectRoot = ""; projectRoot = "";
@@ -125,7 +388,16 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
524FA63E2BCBF4C300133747 /* tt_chocolates_extralight.otf in Resources */,
524FA60F2BCACF0500133747 /* Screen1.json in Resources */,
524FA6412BCBF4C300133747 /* tt_chocolates_demibold.otf in Resources */,
524FA6072BCACDCF00133747 /* Preview Assets.xcassets in Resources */, 524FA6072BCACDCF00133747 /* Preview Assets.xcassets in Resources */,
524FA6452BCBF4C300133747 /* tt_chocolates_bold.otf in Resources */,
524FA6492BCBF4C300133747 /* tt_chocolates_medium.otf in Resources */,
524FA6442BCBF4C300133747 /* tt_chocolates_extrabold.otf in Resources */,
524FA63D2BCBF4C300133747 /* tt_chocolates_light.otf in Resources */,
524FA63F2BCBF4C300133747 /* tt_chocolates_regular.otf in Resources */,
524FA6112BCACF3A00133747 /* Screen2.json in Resources */,
524FA6042BCACDCF00133747 /* Assets.xcassets in Resources */, 524FA6042BCACDCF00133747 /* Assets.xcassets in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@@ -137,8 +409,46 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
524FA6022BCACDCE00133747 /* ContentView.swift in Sources */, 52B222252BD178D000B55575 /* OfferBodyView.swift in Sources */,
52B222332BD17ADC00B55575 /* OfferPictureUrls.swift in Sources */,
524FA6022BCACDCE00133747 /* OffersListScreen.swift in Sources */,
52B222172BD1737500B55575 /* Extension+View.swift in Sources */,
524FA61F2BCAD0FD00133747 /* OfferDetailsResponseDTO.swift in Sources */,
52B222432BD1864100B55575 /* OfferDetailsMapView.swift in Sources */,
52B2221D2BD1756100B55575 /* OffererUserProStatusView.swift in Sources */,
52B2222B2BD17A7F00B55575 /* Relationships.swift in Sources */,
52B2221B2BD1749E00B55575 /* OffererUserInfos.swift in Sources */,
524FA6212BCAD22D00133747 /* HTTPClient.swift in Sources */,
524FA64F2BCC0AA100133747 /* OfferDetailsScreen.swift in Sources */,
524FA6272BCAE1C500133747 /* OfferListView.swift in Sources */,
524FA6252BCAD58400133747 /* AppState.swift in Sources */,
524FA6512BCC115B00133747 /* OffererUserView.swift in Sources */,
52B2221F2BD175E300B55575 /* OffererUserGallery.swift in Sources */,
52B222412BD17DF100B55575 /* OfferDetailsLeaseholderInfosView.swift in Sources */,
524FA6002BCACDCE00133747 /* AlloVictorApp.swift in Sources */, 524FA6002BCACDCE00133747 /* AlloVictorApp.swift in Sources */,
524FA6572BCC34E900133747 /* OfferSocialView.swift in Sources */,
52B2222F2BD17AA100B55575 /* Social.swift in Sources */,
524FA64D2BCBFA3000133747 /* TextModifier.swift in Sources */,
52B222352BD17AEB00B55575 /* OfferersUser.swift in Sources */,
524FA6552BCC339A00133747 /* OfferDetailsView.swift in Sources */,
52B222192BD173FF00B55575 /* OffererUserRatingView.swift in Sources */,
52B222392BD17B1200B55575 /* GalleryPicture.swift in Sources */,
52B2222D2BD17A9100B55575 /* Leaseholder.swift in Sources */,
52B222232BD1782700B55575 /* OfferHeaderView.swift in Sources */,
524FA61D2BCAD0F100133747 /* OfferListResponseDTO.swift in Sources */,
52B2223F2BD17D5800B55575 /* OfferDetailsGalleryView.swift in Sources */,
52B222132BD16DC800B55575 /* OfferDetailsBodyView.swift in Sources */,
524FA6532BCC326500133747 /* ShareView.swift in Sources */,
524FA62C2BCAF2CF00133747 /* AlloFlashView.swift in Sources */,
52B222292BD17A6300B55575 /* Offer.swift in Sources */,
52B222022BD1492600B55575 /* ShowFullPictureScreen.swift in Sources */,
52B222112BD1631600B55575 /* NotFoundScreen.swift in Sources */,
524FA6232BCAD29000133747 /* AlloVictorViewModel.swift in Sources */,
52B222372BD17B0100B55575 /* OfferersUserMeta.swift in Sources */,
52B222312BD17ACB00B55575 /* OfferPicture.swift in Sources */,
525ED7342BCD257C00FE6109 /* AvatarView.swift in Sources */,
52B2223B2BD17BD100B55575 /* OfferDetailsAwnserCountView.swift in Sources */,
524FA61B2BCAD04B00133747 /* Constants.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -275,11 +585,13 @@
DEVELOPMENT_TEAM = WVH3Y23X7X; DEVELOPMENT_TEAM = WVH3Y23X7X;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AlloVictor/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UIUserInterfaceStyle = Light;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -304,11 +616,13 @@
DEVELOPMENT_TEAM = WVH3Y23X7X; DEVELOPMENT_TEAM = WVH3Y23X7X;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES; GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = AlloVictor/Info.plist;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UIUserInterfaceStyle = Light;
LD_RUNPATH_SEARCH_PATHS = ( LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"@executable_path/Frameworks", "@executable_path/Frameworks",
@@ -344,6 +658,25 @@
defaultConfigurationName = Release; defaultConfigurationName = Release;
}; };
/* End XCConfigurationList section */ /* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
524FA6282BCAEC0B00133747 /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/lorenzofiamingo/swiftui-cached-async-image";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.1.1;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
524FA6292BCAEC0B00133747 /* CachedAsyncImage */ = {
isa = XCSwiftPackageProductDependency;
package = 524FA6282BCAEC0B00133747 /* XCRemoteSwiftPackageReference "swiftui-cached-async-image" */;
productName = CachedAsyncImage;
};
/* End XCSwiftPackageProductDependency section */
}; };
rootObject = 524FA5F42BCACDCE00133747 /* Project object */; rootObject = 524FA5F42BCACDCE00133747 /* Project object */;
} }

View File

@@ -0,0 +1,14 @@
{
"pins" : [
{
"identity" : "swiftui-cached-async-image",
"kind" : "remoteSourceControl",
"location" : "https://github.com/lorenzofiamingo/swiftui-cached-async-image",
"state" : {
"revision" : "467a3d17479887943ab917a379e62bbaff60ac8a",
"version" : "2.1.1"
}
}
],
"version" : 2
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Bucket
uuid = "8EB8DC43-4882-4D9C-87F9-B19F0F620F8C"
type = "1"
version = "2.0">
</Bucket>

View File

@@ -9,9 +9,36 @@ import SwiftUI
@main @main
struct AlloVictorApp: App { struct AlloVictorApp: App {
@StateObject private var viewModel = AlloVictorViewModel()
@StateObject private var appState = AppState()
private func fetchOffers() async {
do {
try await viewModel.getDatas()
} catch {
print(error.localizedDescription)
}
}
var body: some Scene { var body: some Scene {
WindowGroup { WindowGroup {
ContentView() NavigationStack(path: $appState.routes) {
OffersListScreen()
.navigationDestination(for: Route.self) { route in
switch route {
case .offers:
OffersListScreen()
case .detail(let offer):
OfferDetailsScreen(offerDetails: offer)
}
}
}
.task {
await fetchOffers()
}
.environmentObject(viewModel)
.environmentObject(appState)
} }
} }
} }

17
AlloVictor/AppState.swift Normal file
View File

@@ -0,0 +1,17 @@
//
// AppState.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import Foundation
enum Route: Hashable {
case offers
case detail(Offer?)
}
class AppState: ObservableObject {
@Published var routes: [Route] = []
}

View File

@@ -1,6 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "Icon.png",
"idiom" : "universal", "idiom" : "universal",
"platform" : "ios", "platform" : "ios",
"size" : "1024x1024" "size" : "1024x1024"

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0xF3",
"green" : "0xCF",
"red" : "0xE6"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0xF3",
"green" : "0xCF",
"red" : "0xE6"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.894",
"green" : "0.843",
"red" : "0.808"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.894",
"green" : "0.843",
"red" : "0.808"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0x31",
"green" : "0x23",
"red" : "0x18"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0x31",
"green" : "0x23",
"red" : "0x18"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "Avatar.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "icon.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "Logo Victor2.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

View File

@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "oups.svg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="693px" height="223px" viewBox="0 0 693 223" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: sketchtool 49 (51002) - http://www.bohemiancoding.com/sketch -->
<title>6F323CAA-B7A5-4B13-98A5-A3266E99B020</title>
<desc>Created with sketchtool.</desc>
<defs>
<linearGradient x1="0%" y1="100%" x2="100%" y2="0%" id="linearGradient-1">
<stop stop-color="#E6007A" offset="0%"></stop>
<stop stop-color="#EB7575" offset="100%"></stop>
</linearGradient>
<linearGradient x1="100%" y1="0%" x2="0%" y2="100%" id="linearGradient-2">
<stop stop-color="#96E077" offset="0%"></stop>
<stop stop-color="#50CC7D" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Desktop" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="Modal-404" transform="translate(-293.000000, -201.000000)">
<g id="illus-404" transform="translate(290.000000, 184.000000)">
<g id="Group" transform="translate(599.537037, 109.761092)">
<path d="M32.1963144,15.0318954 L32.3314996,23.8918857 C32.3847404,27.3681997 30.1977033,30.2210519 27.4463144,30.2641139 L5.21483295,30.6118857 C2.46344406,30.6554157 0.190295914,27.8718369 0.137055173,24.3955229 L0.000944061816,15.4915346 C-0.0319263086,13.3548208 0.795388506,11.3510373 2.19724036,10.1691748 L13.014833,1.05081303 C14.6236292,-0.305169414 16.7157589,-0.352443914 18.376407,0.930052429 L29.7912218,9.74464043 C31.2551107,10.8750159 32.1629811,12.8713104 32.1963144,15.0318954 Z M16.97687,20.6336897 C17.3213144,20.6219881 17.5259441,20.2461324 17.3597404,19.9409544 C16.9657589,19.2187311 16.1935367,18.7408374 15.3222404,18.7712616 C14.4426107,18.8021538 13.6990922,19.3423001 13.3597404,20.1019686 C13.2222404,20.4099549 13.4634441,20.7567906 13.7977033,20.7446209 L16.97687,20.6336897 Z M20.4687681,14.9689408 C20.7872867,14.9675366 21.0595089,14.7171222 21.071083,14.3950939 C21.0715459,14.3768394 21.0720089,14.3585849 21.0715459,14.3403303 C21.0664533,13.4673903 20.283583,12.7835483 19.3909904,12.9548598 C18.9136755,13.0470685 18.5136755,13.4056058 18.3474718,13.8671173 C18.2798792,14.0548111 18.2548792,14.2354839 18.2618237,14.4063274 C18.2757126,14.7278876 18.5493237,14.9768979 18.8678422,14.9759617 C19.4016385,14.9740895 19.9354348,14.9712811 20.4687681,14.9689408 Z M9.33450888,14.4199013 C9.33219406,14.7480144 9.61413851,15.006854 9.93867554,15.0063859 C10.4738607,15.0059179 11.008583,15.0049817 11.5437681,15.0045137 C11.8641385,15.0040456 12.146083,14.7512908 12.145157,14.4273903 L12.145157,14.4208374 C12.1400644,13.5394722 11.3419163,12.8509496 10.4391385,13.0405156 C9.93636073,13.1458301 9.52524962,13.5464932 9.38728665,14.0463859 C9.35210147,14.1746356 9.3354348,14.2991407 9.33450888,14.4199013 Z" id="Fill-26" fill="url(#linearGradient-1)"></path>
<path d="M24.7726852,33.8742857 C24.7726852,34.7453535 20.6782407,35.4516626 15.6273148,35.4516626 C10.5763889,35.4516626 6.48148148,34.7453535 6.48148148,33.8742857 C6.48148148,33.0027499 10.5763889,32.2964408 15.6273148,32.2964408 C20.6782407,32.2964408 24.7726852,33.0027499 24.7726852,33.8742857" id="Fill-24" fill="#E6E6E6" opacity="0.5"></path>
</g>
<g id="Group-8" transform="translate(112.615741, 75.358362)" fill="#333333">
<path d="M60.1157407,118.607509 C25.1157407,118.607509 0,92.2320819 0,59.6313993 L0,59.3037543 C0,26.7030717 25.4398148,0 60.4398148,0 C95.4398148,0 120.555556,26.3754266 120.555556,58.9761092 L120.555556,59.3037543 C120.555556,91.9044369 95.1157407,118.607509 60.1157407,118.607509 Z M60.4398148,95.3447099 C80.5324074,95.3447099 94.4675926,79.2901024 94.4675926,59.6313993 L94.4675926,59.3037543 C94.4675926,39.6450512 80.2083333,23.2627986 60.1157407,23.2627986 C40.0231481,23.2627986 26.087963,39.3174061 26.087963,58.9761092 L26.087963,59.3037543 C26.087963,78.9624573 40.3472222,95.3447099 60.4398148,95.3447099 Z" id="Oups!"></path>
<path d="M218.912037,40.3003413 L218.912037,105.174061 C218.912037,112.054608 213.402778,117.624573 206.597222,117.624573 C199.791667,117.624573 194.282407,112.054608 194.282407,105.174061 L194.282407,104.191126 C188.611111,111.56314 181.319444,118.279863 168.842593,118.279863 C150.208333,118.279863 139.351852,105.829352 139.351852,85.6791809 L139.351852,40.3003413 C139.351852,33.4197952 144.861111,27.8498294 151.666667,27.8498294 C158.472222,27.8498294 163.981481,33.4197952 163.981481,40.3003413 L163.981481,77.8156997 C163.981481,89.6109215 169.490741,95.6723549 178.888889,95.6723549 C188.287037,95.6723549 194.282407,89.6109215 194.282407,77.8156997 L194.282407,40.3003413 C194.282407,33.4197952 199.791667,27.8498294 206.597222,27.8498294 C213.402778,27.8498294 218.912037,33.4197952 218.912037,40.3003413 Z" id="Path"></path>
<path d="M240.625,131.221843 L240.625,40.1365188 C240.625,33.2559727 246.134259,27.6860068 252.939815,27.6860068 C259.74537,27.6860068 265.25463,33.2559727 265.25463,40.1365188 L265.25463,41.2832765 C271.25,33.0921502 279.513889,27.0307167 292.314815,27.0307167 C312.569444,27.0307167 331.851852,43.0853242 331.851852,72.4095563 L331.851852,72.7372014 C331.851852,102.061433 312.893519,118.116041 292.314815,118.116041 C279.189815,118.116041 271.087963,112.054608 265.25463,105.010239 L265.25463,131.221843 C265.25463,138.102389 259.74537,143.672355 252.939815,143.672355 C246.134259,143.672355 240.625,138.102389 240.625,131.221843 Z M285.99537,96.9829352 C297.5,96.9829352 307.222222,87.4812287 307.222222,72.7372014 L307.222222,72.4095563 C307.222222,57.8293515 297.5,48.1638225 285.99537,48.1638225 C274.490741,48.1638225 264.930556,57.8293515 264.930556,72.4095563 L264.930556,72.7372014 C264.930556,87.3174061 274.490741,96.9829352 285.99537,96.9829352 Z" id="Combined-Shape"></path>
<path d="M380.706019,117.952218 C370.011574,117.952218 358.506944,114.83959 347.974537,107.959044 C345.381944,106.320819 343.275463,103.372014 343.275463,99.440273 C343.275463,93.8703072 347.488426,89.6109215 352.997685,89.6109215 C354.780093,89.6109215 356.5625,90.1023891 357.858796,90.9215017 C366.122685,96.1638225 374.386574,98.7849829 381.354167,98.7849829 C388.483796,98.7849829 391.724537,96.1638225 391.724537,92.2320819 L391.724537,91.9044369 C391.724537,86.4982935 383.298611,84.6962457 373.738426,81.7474403 C361.585648,78.1433447 347.8125,72.4095563 347.8125,55.3720137 L347.8125,55.0443686 C347.8125,37.1877133 362.071759,27.1945392 379.571759,27.1945392 C388.645833,27.1945392 398.043981,29.6518771 406.469907,33.9112628 C410.034722,35.7133106 412.303241,38.9897611 412.303241,43.2491468 C412.303241,48.8191126 407.928241,53.0784983 402.418981,53.0784983 C400.636574,53.0784983 399.502315,52.7508532 397.881944,51.9317406 C390.914352,48.4914676 384.270833,46.3617747 379.085648,46.3617747 C373.090278,46.3617747 370.011574,48.9829352 370.011574,52.4232082 L370.011574,52.7508532 C370.011574,57.665529 378.275463,59.9590444 387.673611,63.2354949 C399.826389,67.331058 413.923611,73.2286689 413.923611,89.2832765 L413.923611,89.6109215 C413.923611,109.105802 399.502315,117.952218 380.706019,117.952218 Z" id="Path"></path>
<path d="M439.363426,71.0989761 L432.395833,9.50170648 C431.909722,4.75085324 434.502315,1.14675768 438.877315,1.14675768 L454.756944,1.14675768 C459.131944,1.14675768 461.724537,4.75085324 461.238426,9.50170648 L454.270833,71.0989761 C453.784722,75.5221843 450.868056,78.3071672 446.81713,78.3071672 C442.766204,78.3071672 439.849537,75.5221843 439.363426,71.0989761 Z M432.719907,103.044369 C432.719907,95.1808874 438.715278,89.1194539 446.81713,89.1194539 C454.918981,89.1194539 460.914352,95.1808874 460.914352,103.044369 L460.914352,103.372014 C460.914352,111.235495 454.918981,117.296928 446.81713,117.296928 C438.715278,117.296928 432.719907,111.235495 432.719907,103.372014 L432.719907,103.044369 Z" id="Combined-Shape"></path>
</g>
<g id="Group-7" transform="translate(36.458333, 0.000000)" fill="#F0F0F0">
<path d="M52.447906,67.7199183 C52.488394,70.2230013 50.4958643,72.306291 48.0200622,72.3489671 C45.5399529,72.3925142 43.4785073,70.3762869 43.4380193,67.8697201 L42.751445,25.6578464 C42.710957,23.1547634 44.7034867,21.0706028 47.1792888,21.0279267 C49.6593981,20.9852506 51.7208437,23.0014779 51.7621932,25.5080447 L52.447906,67.7199183 Z M27.7847302,68.5019358 C28.9476853,70.7141247 28.1103576,73.4863283 25.9231406,74.6638399 C23.7333393,75.8422224 20.9887654,74.9947973 19.8249488,72.7808665 L7.60186035,49.5372062 C6.43890528,47.3250173 7.27709438,44.5519427 9.46431136,43.3753021 C11.6532512,42.1969196 14.3978252,43.0443447 15.5625032,45.2582755 L27.7847302,68.5019358 Z M67.3890358,68.5019358 L79.6112628,45.2582755 C80.7759408,43.0443447 83.5205148,42.1969196 85.7103161,43.3753021 C87.8975331,44.5519427 88.7348607,47.3250173 87.5719056,49.5372062 L75.3488172,72.7808665 C74.1850006,74.9947973 71.4404267,75.8422224 69.2514868,74.6638399 C67.0642698,73.4863283 66.2260807,70.7141247 67.3890358,68.5019358 Z" id="Combined-Shape" transform="translate(47.586979, 48.111341) rotate(-45.000000) translate(-47.586979, -48.111341) "></path>
<path d="M589.600684,67.7199183 C589.641172,70.2230013 587.648642,72.306291 585.17284,72.3489671 C582.692731,72.3925142 580.631285,70.3762869 580.590797,67.8697201 L579.904223,25.6578464 C579.863735,23.1547634 581.856264,21.0706028 584.332067,21.0279267 C586.812176,20.9852506 588.873621,23.0014779 588.914971,25.5080447 L589.600684,67.7199183 Z M564.937508,68.5019358 C566.100463,70.7141247 565.263135,73.4863283 563.075918,74.6638399 C560.886117,75.8422224 558.141543,74.9947973 556.977727,72.7808665 L544.754638,49.5372062 C543.591683,47.3250173 544.429872,44.5519427 546.617089,43.3753021 C548.806029,42.1969196 551.550603,43.0443447 552.715281,45.2582755 L564.937508,68.5019358 Z M604.541814,68.5019358 L616.764041,45.2582755 C617.928719,43.0443447 620.673293,42.1969196 622.863094,43.3753021 C625.050311,44.5519427 625.887638,47.3250173 624.724683,49.5372062 L612.501595,72.7808665 C611.337778,74.9947973 608.593204,75.8422224 606.404265,74.6638399 C604.217048,73.4863283 603.378859,70.7141247 604.541814,68.5019358 Z" id="Combined-Shape" transform="translate(584.739757, 48.111341) rotate(-315.000000) translate(-584.739757, -48.111341) "></path>
</g>
<g id="Group-2" transform="translate(636.805556, 143.344710)">
<path d="M39.3226709,52.0542148 C39.3226709,53.4115293 32.9426291,54.5128431 25.0721794,54.5128431 C17.2017298,54.5128431 10.8209665,53.4115293 10.8209665,52.0542148 C10.8209665,50.6969003 17.2017298,49.5955865 25.0721794,49.5955865 C32.9426291,49.5955865 39.3226709,50.6969003 39.3226709,52.0542148" id="Fill-8" fill="#E6E6E6" opacity="0.5"></path>
<path d="M33.1159086,23.031178 C32.273316,22.909377 31.4307234,22.7875761 30.5874094,22.6665045 C30.082431,22.5928405 29.694319,22.1311639 29.7664587,21.6206211 C29.7671801,21.6177037 29.7671801,21.614057 29.7679015,21.6104103 C29.9713357,20.2231925 31.3802255,19.3180731 32.7609809,19.8205931 C33.5299909,20.1006623 34.0897956,20.8241744 34.1965624,21.6432309 C34.2239755,21.8525534 34.2225328,22.0531238 34.1972838,22.2434833 C34.128751,22.7605903 33.6266582,23.104842 33.1159086,23.031178 M22.3007132,33.172746 C20.647991,32.6673087 19.7130595,30.903748 20.2129881,29.2328143 C20.7121954,27.5618807 22.4572566,26.6173765 24.1099788,27.1220845 C25.7627011,27.6267925 26.6976326,29.3910826 26.197704,31.0612869 C25.6984967,32.7322205 23.9534355,33.6774541 22.3007132,33.172746 M18.4123793,20.9095079 C17.5719509,20.7862483 16.7322439,20.6608007 15.8918155,20.537541 C15.390444,20.4631477 15.01676,20.0080352 15.069422,19.4982218 C15.073029,19.4690479 15.076636,19.4406034 15.0809644,19.4114295 C15.2822344,18.03734 16.6665967,17.1358673 18.0343668,17.6070254 C18.7665856,17.8593794 19.3177335,18.5157915 19.4771624,19.2801471 C19.5420882,19.5908488 19.5428096,19.8811289 19.4930331,20.1487992 C19.4006942,20.6527778 18.9137507,20.9824426 18.4123793,20.9095079 M49.6878581,41.3086103 L51.8628724,27.6778468 C52.3930997,24.3534838 51.537522,21.0415197 49.5955192,18.9045334 L34.4519372,2.24187504 C32.2487885,-0.182473923 29.0263046,-0.685723257 26.1933756,0.953119139 L7.14342475,11.9691741 C4.67408019,13.3972353 2.86625738,16.2438761 2.34180121,19.5310424 L0.15596597,33.2303645 C-0.698168987,38.578665 2.04169973,43.4740411 6.27414044,44.1647326 L40.4784942,49.7427774 C44.7109349,50.4334689 48.8344445,46.6569108 49.6878581,41.3086103" id="Fill-14" fill="url(#linearGradient-2)"></path>
</g>
<g id="Group-3" transform="translate(107.754630, 170.375427)">
<path d="M50.4712963,65.876314 C50.4712963,67.6184495 42.2824074,69.0310678 32.1805556,69.0310678 C22.0787037,69.0310678 13.8888889,67.6184495 13.8888889,65.876314 C13.8888889,64.1341784 22.0787037,62.7206241 32.1805556,62.7206241 C42.2824074,62.7206241 50.4712963,64.1341784 50.4712963,65.876314" id="Fill-57" fill="#E6E6E6" opacity="0.5"></path>
<path d="M64.4267183,49.0298464 C64.4333719,55.9830258 59.9775869,61.6313184 54.4735227,61.6433861 L10.0028256,61.7543311 C4.49955438,61.7683311 0.033874226,56.1427566 0.0272859286,49.1886434 L0.0112356361,31.3792262 C0.00743470768,27.1063585 1.71927387,23.1204979 4.55695181,20.7945923 L26.4531188,2.84517174 C29.7092812,0.175978774 33.895315,0.137434404 37.1797512,2.74504727 L59.7544781,20.6736244 C62.6493839,22.9715358 64.4078191,26.9870416 64.4109301,31.309597 L64.4267183,49.0298464 Z M43.5342436,31.7153716 C44.1944288,31.6554594 44.7212807,31.0759957 44.6555399,30.4094721 C44.6323918,30.1642064 44.5749844,29.9133239 44.479614,29.659633 C44.1083177,28.6682727 43.1981325,27.9315394 42.1564658,27.8098426 C40.2851696,27.5935969 38.7879473,29.143826 38.9379473,30.9374487 C38.9388733,30.9421293 38.9388733,30.9458738 38.9397992,30.9505545 C38.9981325,31.6095891 39.617577,32.0711006 40.2694288,32.0121244 C41.3573918,31.9128948 42.4462807,31.8136652 43.5342436,31.7153716 Z M24.5481325,33.441593 C25.1953547,33.383553 25.7083177,32.8265564 25.6759103,32.1693941 C25.6592436,31.8202181 25.5749844,31.4588724 25.4036881,31.0891015 C24.9814658,30.1810567 24.1018362,29.5257666 23.1138733,29.4293453 C21.267577,29.2468002 19.7999844,30.7848597 19.9490584,32.561632 C19.9518362,32.5990771 19.9564658,32.6365223 19.9610955,32.6730313 C20.042577,33.3264492 20.641651,33.7842161 21.2907251,33.7271123 C22.3759103,33.6316271 23.4620214,33.5370781 24.5481325,33.441593 Z M42.576651,43.0193131 C43.2460955,42.8863829 43.6868362,42.2236037 43.5553547,41.5477188 C43.4247992,40.8699616 42.7692436,40.4253005 42.0988733,40.5572946 L25.664614,43.8168948 C24.9951696,43.9488889 24.5553547,44.6116681 24.6868362,45.2884891 L24.6868362,45.2894253 C24.8173918,45.9653102 25.4729473,46.4109075 26.1423918,46.2779772 L42.576651,43.0193131 Z" id="Fill-61" fill="url(#linearGradient-2)"></path>
</g>
<g id="Group-5" transform="translate(9.722222, 147.440273)">
<path d="M51.2942568,56.1673634 C51.2942568,57.5114151 44.978019,58.6009384 37.1862208,58.6009384 C29.3944225,58.6009384 23.0774854,57.5114151 23.0774854,56.1673634 C23.0774854,54.8233117 29.3944225,53.7337884 37.1862208,53.7337884 C44.978019,53.7337884 51.2942568,54.8233117 51.2942568,56.1673634" id="Fill-1" fill="#E6E6E6" opacity="0.5"></path>
<path d="M47.9124737,30.9599224 C47.7935897,31.4513037 47.2746959,31.730578 46.7900687,31.6068489 C45.9893499,31.4018121 45.1900297,31.1960682 44.3900102,30.9917384 C43.9102783,30.8687163 43.5836969,30.3829912 43.7046788,29.8986801 C43.7060775,29.8951449 43.7067768,29.8923168 43.7074761,29.8887817 C44.0445473,28.5730109 45.4949323,27.8468978 46.7746837,28.4754417 C47.4872885,28.8247113 47.9530341,29.5805195 47.972615,30.3808701 C47.9775102,30.5859069 47.9558314,30.7789244 47.9124737,30.9599224 Z M40.4615173,41.879251 C39.8217315,38.9806608 37.9149716,36.665969 35.2223883,35.9784105 C32.5303567,35.2911578 29.7293,36.4034943 27.7508758,38.6338779 C27.2686064,39.1773494 27.4472068,40.0820432 28.0582829,40.2377553 L39.4075374,43.1353566 C40.0186135,43.2910688 40.6174471,42.5854489 40.4615173,41.879251 Z M29.7546886,26.321848 C29.7602831,26.2942741 29.7672763,26.2674072 29.7742695,26.2398333 C30.1085434,24.9360819 31.5344522,24.2113828 32.8051126,24.8081106 C33.4848494,25.1276853 33.9498957,25.8177402 34.0261213,26.5707203 C34.0568913,26.8775685 34.02752,27.1568428 33.952693,27.4099572 C33.8121301,27.8857841 33.3093207,28.153746 32.8337846,28.0300169 C32.0358631,27.824273 31.2386408,27.6164081 30.4414186,27.4099572 C29.9651832,27.2862281 29.6518889,26.8075732 29.7546886,26.321848 Z M44.3204505,10.5153489 C42.4434817,7.94956048 39.3888618,7.12870616 36.4908891,8.41336792 L17.0064983,17.0482463 C14.4812619,18.1674646 12.4483453,20.7233546 11.6077654,23.8370863 L8.1048828,36.8145032 C6.73771662,41.8810338 8.87972685,46.8846393 12.8889154,47.9911312 L45.2904042,56.9293227 C49.2995928,58.0358145 53.6591396,54.8252206 55.0263058,49.75869 L58.5110061,36.8463192 C59.3613765,33.6972364 58.873952,30.4152332 57.2193662,28.1534649 L44.3204505,10.5153489 Z" id="Fill-3" fill="url(#linearGradient-1)" transform="translate(33.307205, 32.481173) rotate(-21.000000) translate(-33.307205, -32.481173) "></path>
</g>
<g id="Group-4" transform="translate(64.004630, 121.228669)">
<path d="M25.7001366,32.912214 C25.7001366,33.8685073 21.353488,34.6444357 15.9914419,34.6444357 C10.6289042,34.6444357 6.28225562,33.8685073 6.28225562,32.912214 C6.28225562,31.9559206 10.6289042,31.1799922 15.9914419,31.1799922 C21.353488,31.1799922 25.7001366,31.9559206 25.7001366,32.912214" id="Fill-6" fill="#E6E6E6" opacity="0.5"></path>
<path d="M14.1607387,20.3397612 C14.6049162,19.5579956 15.1997885,18.8469862 15.9433341,18.2554837 C18.2789201,16.3960192 21.4116058,16.2259643 23.8958519,17.5653046 C24.3959372,17.8347414 24.6204241,18.4830107 24.3022613,18.9544426 C24.0143708,19.3812257 23.4850873,19.4738227 23.0695681,19.2441446 C21.2124129,18.2203894 18.8558885,18.3372493 17.1020753,19.7333047 C16.5503621,20.171913 16.1120938,20.6998853 15.7841079,21.2810244 C15.5288582,21.7320465 14.9482803,21.8734029 14.5092463,21.5972493 C14.5038823,21.5941194 14.4983915,21.590516 14.4930276,21.5873861 C14.0727231,21.3229602 13.9158454,20.771262 14.1607387,20.3397612 M20.6125571,11.2872501 C21.1550567,11.1465705 21.696585,11.0058908 22.2390846,10.8657013 C22.5630303,10.7823719 22.9049459,10.9637359 23.0001383,11.2867599 C23.0511342,11.4588107 23.0710469,11.6485076 23.0501629,11.856341 C22.9981956,12.3680817 22.6825065,12.8361969 22.2201433,13.0528534 C21.3561264,13.4582265 20.3862322,12.9665829 20.1589361,12.0813304 C20.1540793,12.0627039 20.1497082,12.0440773 20.1458228,12.0254507 C20.0758855,11.6955643 20.2886114,11.3710697 20.6125571,11.2872501 M13.950096,13.6980131 C13.9797222,13.8205564 13.9947782,13.9519228 13.9913784,14.0911319 C13.9782652,14.6342436 13.661119,15.1474548 13.1769005,15.3846985 C12.3065698,15.8111491 11.3201627,15.3185252 11.0909238,14.4249397 C11.0904381,14.422979 11.0899524,14.4210184 11.0889811,14.4190577 C11.0064162,14.0901516 11.2288556,13.7597749 11.554744,13.6764455 C12.0987006,13.5377266 12.643143,13.3980272 13.1870996,13.2588181 C13.5168734,13.1749985 13.8694739,13.3642053 13.950096,13.6980131 M34.5574836,19.6860052 L32.1752448,10.8766155 C31.6036046,8.76298936 30.2213719,7.02777684 28.504023,6.26800864 L15.2538213,0.406029385 C13.2834354,-0.465498262 11.2057152,0.0913382999 9.92984542,1.83292307 L1.15805846,13.8068698 C0.0332337716,15.3425819 -0.298968337,17.5704184 0.2794713,19.7080629 L2.64908254,28.4733371 C3.57915131,31.9128812 6.54371516,34.0921905 9.27029796,33.3417356 L31.3039428,27.2733935 C34.0305256,26.5224484 35.4870667,23.1255493 34.5574836,19.6860052" id="Fill-12" fill="url(#linearGradient-2)"></path>
</g>
<g id="Group-6" transform="translate(551.736111, 170.375427)">
<path d="M63.4722064,29.9219664 L63.9825089,47.3859091 C64.1824307,54.2387668 59.9493842,59.9250236 54.5259361,60.0874617 L10.7019925,61.398042 C5.27945726,61.5595571 0.720510993,56.1354164 0.519676356,49.2834816 L0.00663514578,31.7309362 C-0.115691406,27.5204666 1.45994761,23.5453476 4.19129868,21.1761509 L25.2698068,2.89447997 C28.40374,0.175487514 32.5281531,0.0241247297 35.8373602,2.50592062 L58.5855345,19.564691 C61.503114,21.7529908 63.3471411,25.6625807 63.4722064,29.9219664 Z M38.2554093,33.873458 C38.883474,33.8706892 39.4202502,33.3769142 39.4430723,32.7419289 C39.4439852,32.7059341 39.4448981,32.6699393 39.4439852,32.6339445 C39.4339434,30.9126543 37.8902554,29.5642334 36.1302137,29.9020308 C35.1890295,30.0838507 34.4002971,30.7908257 34.0725715,31.7008483 C33.9392903,32.0709487 33.8899946,32.4272051 33.9036878,32.7640795 C33.9310744,33.3981419 34.4705892,33.889148 35.0986539,33.8873022 C36.15121,33.8836104 37.2037661,33.8780727 38.2554093,33.873458 Z M16.3005319,32.7908449 C16.2959674,33.4378285 16.8519142,33.9482164 17.4918464,33.9472935 C18.5471411,33.9463706 19.601523,33.9445247 20.6568177,33.9436017 C21.2885339,33.9426788 21.8444807,33.4442891 21.842655,32.805612 L21.842655,32.7926908 C21.8326132,31.0547876 20.2588,29.6971373 18.4786748,30.0709295 C17.487282,30.2785919 16.6766404,31.0686318 16.4046007,32.0543358 C16.3352215,32.3072224 16.3023576,32.5527254 16.3005319,32.7908449 Z M19.9107193,44.2398067 C19.3620756,44.842489 19.4122843,45.7838917 19.9892274,46.3607315 C19.9965305,46.3681151 20.0038336,46.3745757 20.0111367,46.3819592 C20.6127277,46.9846415 21.5940788,46.9689515 22.1655446,46.3385809 C22.9013297,45.5282362 23.7950438,44.8397201 24.8366453,44.3367158 C28.1504168,42.7381771 31.9626234,43.4091572 34.5606933,45.7257462 C35.1431137,46.2444406 36.0222217,46.2896649 36.6393318,45.7091332 C37.3194309,45.0695332 37.1961914,43.9500023 36.4932702,43.3353217 C33.0069635,40.2849925 27.9331502,39.4174253 23.5202655,41.5475796 C22.1162488,42.2240974 20.9057637,43.1470412 19.9107193,44.2398067 Z" id="Fill-16" fill="url(#linearGradient-1)"></path>
<path d="M50.3877384,65.29951 C50.3877384,67.0171084 42.314186,68.4098306 32.3546138,68.4098306 C22.3941286,68.4098306 14.3205762,67.0171084 14.3205762,65.29951 C14.3205762,63.5809886 22.3941286,62.1882664 32.3546138,62.1882664 C42.314186,62.1882664 50.3877384,63.5809886 50.3877384,65.29951" id="Fill-20" fill="#E6E6E6" opacity="0.5"></path>
</g>
<path d="M9.67027569,173.710503 C9.6783733,174.211119 9.27986737,174.627777 8.78470694,174.636313 C8.28868507,174.645022 7.87639596,174.241776 7.86829835,173.740463 L7.73098351,165.298088 C7.72288589,164.797472 8.12139183,164.38064 8.61655225,164.372104 C9.11257413,164.363569 9.52486323,164.766815 9.53313314,165.268128 L9.67027569,173.710503 Z M4.73764054,173.866906 C4.97023155,174.309344 4.80276602,174.863785 4.36532262,175.099287 C3.92736236,175.334964 3.37844757,175.165479 3.14568426,174.722692 L0.701066568,170.07396 C0.468475554,169.631523 0.636113374,169.076908 1.07355677,168.84158 C1.51134474,168.605903 2.06025954,168.775388 2.29319513,169.218174 L4.73764054,173.866906 Z M12.6585017,173.866906 L15.1029471,169.218174 C15.3358827,168.775388 15.8847975,168.605903 16.3227577,168.84158 C16.7602011,169.076908 16.9276666,169.631523 16.6950756,170.07396 L14.2504579,174.722692 C14.0176946,175.165479 13.4687798,175.334964 13.0309919,175.099287 C12.5935485,174.863785 12.4259106,174.309344 12.6585017,173.866906 Z" id="Combined-Shape" fill="#E6E6E6" transform="translate(8.698090, 169.788787) rotate(-65.000000) translate(-8.698090, -169.788787) "></path>
<path d="M691.516866,152.574507 C691.524963,153.075123 691.126457,153.491781 690.631297,153.500316 C690.135275,153.509026 689.722986,153.10578 689.714888,152.604467 L689.577573,144.162092 C689.569476,143.661476 689.967982,143.244644 690.463142,143.236108 C690.959164,143.227573 691.371453,143.630819 691.379723,144.132132 L691.516866,152.574507 Z M686.58423,152.73091 C686.816821,153.173348 686.649356,153.727789 686.211913,153.963291 C685.773952,154.198968 685.225038,154.029482 684.992274,153.586696 L682.547657,148.937964 C682.315066,148.495526 682.482703,147.940912 682.920147,147.705583 C683.357935,147.469907 683.906849,147.639392 684.139785,148.082178 L686.58423,152.73091 Z M694.505092,152.73091 L696.949537,148.082178 C697.182473,147.639392 697.731387,147.469907 698.169348,147.705583 C698.606791,147.940912 698.774257,148.495526 698.541666,148.937964 L696.097048,153.586696 C695.864285,154.029482 695.31537,154.198968 694.877582,153.963291 C694.440138,153.727789 694.272501,153.173348 694.505092,152.73091 Z" id="Combined-Shape" fill="#E6E6E6" transform="translate(690.544680, 148.652791) rotate(55.000000) translate(-690.544680, -148.652791) "></path>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -1,24 +0,0 @@
//
// ContentView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
Text("Hello, world!")
}
.padding()
}
}
#Preview {
ContentView()
}

View File

@@ -0,0 +1,13 @@
//
// OfferDetailsResponseDTO.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import Foundation
struct OfferDetailsResponseDTO: Codable {
let format: String
let data: Offer
}

View File

@@ -0,0 +1,13 @@
//
// OfferListResponseDTO.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import Foundation
struct OfferListResponseDTO: Codable {
let format: String
let data: [Offer]
}

View File

@@ -0,0 +1,16 @@
//
// Extension+View.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
extension View {
public func addBorder<S>(_ content: S, width: CGFloat = 1, cornerRadius: CGFloat) -> some View where S : ShapeStyle {
let roundedRect = RoundedRectangle(cornerRadius: cornerRadius)
return clipShape(roundedRect)
.overlay(roundedRect.strokeBorder(content, lineWidth: width))
}
}

16
AlloVictor/Info.plist Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIAppFonts</key>
<array>
<string>tt_chocolates_extralight.otf</string>
<string>tt_chocolates_light.otf</string>
<string>tt_chocolates_medium.otf</string>
<string>tt_chocolates_regular.otf</string>
<string>tt_chocolates_demibold.otf</string>
<string>tt_chocolates_bold.otf</string>
<string>tt_chocolates_extrabold.otf</string>
</array>
</dict>
</plist>

View File

@@ -0,0 +1,20 @@
//
// GalleryPicture.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct GalleryPicture: Codable, Identifiable {
let id: Int
let imageLarge: String
let imageSmall: String
enum CodingKeys: String, CodingKey {
case id
case imageLarge
case imageSmall
}
}

View File

@@ -0,0 +1,22 @@
//
// Leaseholder.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct Leaseholder: Codable, Identifiable {
let id: Int
let displayName: String
let avatarUrl: String
let userRatings: Int
enum CodingKeys: String, CodingKey {
case id
case displayName
case avatarUrl
case userRatings
}
}

View File

@@ -0,0 +1,55 @@
//
// Offer.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
enum CardType: String, Codable {
case alloFlash = "card_blog_alloflash"
case publicSearch = "card_search_public"
}
struct Offer: Codable, Identifiable, Hashable {
var id: Int
let latitude: Double?
let longitude: Double?
let cardType: CardType?
let desc: String?
let objectName: String?
let sectionBackgroundImage: String?
let relationships: Relationships
let publishedAtFormatted: String?
let searchPictureUrl: String?
let locationFormatted: String?
let distanceFormatted: String?
let budgetFormatted: String?
let pictures: [OfferPicture]?
enum CodingKeys: String, CodingKey {
case id = "refId"
case latitude
case longitude
case cardType
case desc = "description"
case objectName
case sectionBackgroundImage
case relationships
case publishedAtFormatted
case searchPictureUrl
case locationFormatted
case distanceFormatted
case budgetFormatted
case pictures
}
public func hash(into hasher: inout Hasher) {
hasher.combine(id)
}
public static func == (lhs: Offer, rhs: Offer) -> Bool {
return lhs.id == rhs.id
}
}

View File

@@ -0,0 +1,18 @@
//
// OfferPicture.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct OfferPicture: Codable, Identifiable {
let id: Int
let pictureUrls: OfferPictureUrls
enum CodingKeys: String, CodingKey {
case id
case pictureUrls
}
}

View File

@@ -0,0 +1,13 @@
//
// OfferPictureUrls.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct OfferPictureUrls: Codable {
let large: String
let small: String
}

View File

@@ -0,0 +1,42 @@
//
// OfferersUser.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct OfferersUser: Codable, Identifiable {
let id: Int
let displayName: String
let firstName: String
let avatarUrl: String
let headline: String
let reviewsCount: Int
let averageRating: Double
let onlineLatestActivityAt: Int
let onlineLatestActivityAtFormatted: String
let distanceFormatted: String
let locationFormatted: String
let isIndependent: Bool
let relationships: Relationships
let meta: OfferersUserMeta
enum CodingKeys: String, CodingKey {
case id = "refId"
case displayName
case firstName
case headline
case avatarUrl
case reviewsCount
case averageRating
case onlineLatestActivityAt
case onlineLatestActivityAtFormatted
case distanceFormatted
case locationFormatted
case isIndependent
case relationships
case meta
}
}

View File

@@ -0,0 +1,16 @@
//
// OfferersUserMeta.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct OfferersUserMeta: Codable {
let answeredAtFormatted: String
enum CodingKeys: String, CodingKey {
case answeredAtFormatted
}
}

View File

@@ -0,0 +1,22 @@
//
// Relationships.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct Relationships: Codable {
let leaseholder: Leaseholder?
let social: Social?
let offerersUsers: [OfferersUser]?
let galleryPictures: [GalleryPicture]?
enum CodingKeys: String, CodingKey {
case leaseholder
case social
case offerersUsers
case galleryPictures
}
}

View File

@@ -0,0 +1,20 @@
//
// Social.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import Foundation
struct Social: Codable {
let likesCount: Int
let answerersCount: Int?
let shareLink: String?
enum CodingKeys: String, CodingKey {
case likesCount
case answerersCount
case shareLink
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,495 @@
{
"format": "json",
"data": [
{
"links": {
"self": "https://www.allovoisins.com/s/8734007"
},
"budget": 0,
"ref_id": 8734007,
"datetime": "2023-12-15 15:43:08",
"duration": 1,
"end_date": null,
"latitude": 47.2132,
"only_pro": false,
"ref_type": "search",
"card_type": "card_search_public",
"city_name": "Nantes",
"longitude": -1.55524,
"object_id": 5392,
"start_date": null,
"category_id": 124,
"description": "Bonjour, Je cherche quelqu'un en mesure de fixer une plainte / moulure arrachée sur un pan de mon mur suite à la chute d'un miroir. Merci par avance Lucie",
"object_name": "Bricolage - Petits travaux",
"ref_type_id": 101,
"search_type": 4,
"card_type_id": 301,
"district_name": "Gloriette-Feydeau",
"duration_type": 3,
"relationships": {
"moment": null,
"social": {
"type": "social",
"answerers_count": 4,
"likes_count": 1,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8734007?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
},
"leaseholder": {
"id": 5539939,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar9.png",
"is_favorite": false,
"is_new_user": true,
"display_name": "Lucie A.",
"user_ratings": 0,
"part_pro_status": 0,
"user_ratings_count": 0
}
},
"budget_formatted": "À convenir",
"duration_formatted": "",
"location_formatted": "Nantes (Gloriette-Feydeau)",
"search_picture_url": null,
"search_picture_urls": [],
"is_category_regulated": false,
"search_pictures_count": 0,
"published_at_formatted": "postée le 15 déc.",
"published_at_formatted_year": "demande postée le 15 déc. 2023",
"distance_formatted": "600 m"
},
{
"links": {
"self": "https://www.allovoisins.com/s/8731481"
},
"budget": 0,
"ref_id": 8731481,
"datetime": "2023-12-14 23:13:12",
"duration": 1,
"end_date": null,
"latitude": 47.2102,
"only_pro": false,
"ref_type": "search",
"card_type": "card_search_public",
"city_name": "Nantes",
"longitude": -1.5498,
"object_id": 5392,
"start_date": null,
"category_id": 124,
"description": "Bonjour, Je cherche à changer le plan de travail de ma cuisine ( découpe évier et plaque électrique) plus pose 1meuble haut sur carquefou",
"object_name": "Bricolage - Petits travaux",
"ref_type_id": 101,
"search_type": 4,
"card_type_id": 301,
"district_name": "Madeleine",
"duration_type": 3,
"relationships": {
"moment": null,
"social": {
"type": "social",
"answerers_count": 9,
"likes_count": 2,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8731481?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
},
"leaseholder": {
"id": 4730931,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar1.png",
"is_favorite": false,
"is_new_user": false,
"display_name": "Franck R.",
"user_ratings": 0,
"part_pro_status": 0,
"user_ratings_count": 0
}
},
"budget_formatted": "À convenir",
"duration_formatted": "",
"location_formatted": "Nantes (Madeleine)",
"search_picture_url": null,
"search_picture_urls": [],
"is_category_regulated": false,
"search_pictures_count": 0,
"published_at_formatted": "postée le 14 déc.",
"published_at_formatted_year": "demande postée le 14 déc. 2023",
"distance_formatted": "500 m"
},
{
"card_type_id": 394,
"ref_type_id": 110,
"ref_id": 658,
"tags": {
"newsfeed_all": 0,
"perimetre_all": 0,
"perimetre_pro_ap": 1,
"perimetre_part_ap": 0,
"perimetre_pro_non_abonne": 0,
"perimetre_part_non_abonne": 0
},
"datetime": "2022-12-12 12:00:16",
"ref_type": "blog",
"card_type": "card_blog_alloflash",
"section_link": "https://www.allovoisins.com/espace-pro",
"section_type": "section_image",
"date_formatted": "Il y a 12 mois",
"is_commentable": false,
"category_formatted": "AlloFlash",
"section_background_image": "https://blog.allovoisins.com/wp-content/uploads/2022/12/alloflash-logiciel-pro.png",
"relationships": {
"social": {
"type": "social",
"answerers_count": null,
"likes_count": 129,
"shares_count": 0,
"recommendations_count": null,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/article/658-?utm_source=product_transactionnel&utm_medium=share&utm_campaign=blog",
"comments_count": 0,
"comments": null
}
}
},
{
"links": {
"self": "https://www.allovoisins.com/s/8702434"
},
"budget": 30,
"ref_id": 8702434,
"datetime": "2023-12-08 21:08:10",
"duration": 1,
"end_date": null,
"latitude": 47.2171,
"only_pro": false,
"ref_type": "search",
"card_type": "card_search_public",
"city_name": "Nantes",
"longitude": -1.54593,
"object_id": 5392,
"start_date": null,
"category_id": 124,
"description": "Bonjour, Je dois installer un spot extérieur au dessus de mon magasin en centre ville de Nantes et je cherche quelqu'un avec une échelle d'au moins 5 mètre qui puissent me le fixer en hauteur (le branchement sera déjà fait). C'est l'histoire de quelques minutes . Merci",
"object_name": "Bricolage - Petits travaux",
"ref_type_id": 101,
"search_type": 4,
"card_type_id": 301,
"district_name": "Richebourg-Saint-Clément",
"duration_type": 1,
"relationships": {
"moment": null,
"social": {
"type": "social",
"answerers_count": 2,
"likes_count": 0,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8702434?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
},
"leaseholder": {
"id": 3230135,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar5.png",
"is_favorite": false,
"is_new_user": false,
"display_name": "Christophe",
"user_ratings": 0,
"part_pro_status": 0,
"user_ratings_count": 0
}
},
"budget_formatted": "30€ / heure",
"duration_formatted": "",
"location_formatted": "Nantes (Richebourg-Saint-Clément)",
"search_picture_url": null,
"search_picture_urls": [],
"is_category_regulated": false,
"search_pictures_count": 0,
"published_at_formatted": "postée le 08 déc.",
"published_at_formatted_year": "demande postée le 08 déc. 2023",
"distance_formatted": "400 m"
},
{
"links": {
"self": "https://www.allovoisins.com/s/8700262"
},
"budget": 0,
"ref_id": 8700262,
"datetime": "2023-12-08 12:55:10",
"duration": 1,
"end_date": null,
"latitude": 47.2146,
"only_pro": false,
"ref_type": "search",
"card_type": "card_search_public",
"city_name": "Nantes",
"longitude": -1.55719,
"object_id": 5392,
"start_date": null,
"category_id": 124,
"description": "Bonjour, J'ai besoin d'une personne bricoleuse multi services pour des finitions dans un appartement dans le centre ville de Nantes",
"object_name": "Bricolage - Petits travaux",
"ref_type_id": 101,
"search_type": 4,
"card_type_id": 301,
"district_name": "Graslin-Commerce",
"duration_type": 3,
"relationships": {
"moment": null,
"social": {
"type": "social",
"answerers_count": 14,
"likes_count": 0,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8700262?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
},
"leaseholder": {
"id": 5063804,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/uploads/u/avatars/3/2/b/32bb61f4ba_5063804_m.jpg",
"is_favorite": false,
"is_new_user": false,
"display_name": "Rolland T.",
"user_ratings": 5,
"part_pro_status": 0,
"user_ratings_count": 1
}
},
"budget_formatted": "À convenir",
"duration_formatted": "",
"location_formatted": "Nantes (Graslin-Commerce)",
"search_picture_url": null,
"search_picture_urls": [],
"is_category_regulated": false,
"search_pictures_count": 0,
"published_at_formatted": "postée le 08 déc.",
"published_at_formatted_year": "demande postée le 08 déc. 2023",
"distance_formatted": "700 m"
},
{
"links": {
"self": "https://www.allovoisins.com/s/8695834"
},
"budget": 0,
"ref_id": 8695834,
"datetime": "2023-12-07 12:31:11",
"duration": 1,
"end_date": null,
"latitude": 47.2125,
"only_pro": false,
"ref_type": "search",
"card_type": "card_search_public",
"city_name": "Nantes",
"longitude": -1.55933,
"object_id": 5392,
"start_date": null,
"category_id": 124,
"description": "Bonjour, je souhaite que quelqu'un m'installe un chien de porte sur ma porte d'entrée en appartement. Il faut l'a redecouper sur quelques centimètres :)",
"object_name": "Bricolage - Petits travaux",
"ref_type_id": 101,
"search_type": 4,
"card_type_id": 301,
"district_name": "Graslin-Commerce",
"duration_type": 3,
"relationships": {
"moment": null,
"social": {
"type": "social",
"answerers_count": 5,
"likes_count": 1,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8695834?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
},
"leaseholder": {
"id": 5046469,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/uploads/u/avatars/4/b/4/4b4d29b6a4_5046469_m.jpg",
"is_favorite": false,
"is_new_user": false,
"display_name": "Bun N.",
"user_ratings": 5,
"part_pro_status": 0,
"user_ratings_count": 2
}
},
"budget_formatted": "À convenir",
"duration_formatted": "",
"location_formatted": "Nantes (Graslin-Commerce)",
"search_picture_url": null,
"search_picture_urls": [],
"is_category_regulated": false,
"search_pictures_count": 0,
"published_at_formatted": "postée le 07 déc.",
"published_at_formatted_year": "demande postée le 07 déc. 2023",
"distance_formatted": "900 m"
},
{
"links": {
"self": "https://www.allovoisins.com/s/8685235"
},
"budget": 0,
"ref_id": 8685235,
"datetime": "2023-12-05 09:01:03",
"duration": 1,
"end_date": null,
"latitude": 47.2094,
"only_pro": false,
"ref_type": "search",
"card_type": "card_search_public",
"city_name": "Nantes",
"longitude": -1.55641,
"object_id": 5392,
"start_date": null,
"category_id": 124,
"description": "Bonjour, je cherche quelqu'un pour poser un meuble de cuisine mural. C'est sur du placo et du béton derrière. Par contre dans le colis il n'y avait pas les vis pour la pose. Si quelqu'un peut le faire n'hésitez pas m'écrire. Merci.",
"object_name": "Bricolage - Petits travaux",
"ref_type_id": 101,
"search_type": 4,
"card_type_id": 301,
"district_name": "Gloriette-Feydeau",
"duration_type": 3,
"relationships": {
"moment": null,
"social": {
"type": "social",
"answerers_count": 9,
"likes_count": 3,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8685235?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
},
"leaseholder": {
"id": 3613005,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar5.png",
"is_favorite": false,
"is_new_user": false,
"display_name": "Céline",
"user_ratings": 0,
"part_pro_status": 0,
"user_ratings_count": 0
}
},
"budget_formatted": "À convenir",
"duration_formatted": "",
"location_formatted": "Nantes (Gloriette-Feydeau)",
"search_picture_url": null,
"search_picture_urls": [],
"is_category_regulated": false,
"search_pictures_count": 0,
"published_at_formatted": "postée le 05 déc.",
"published_at_formatted_year": "demande postée le 05 déc. 2023",
"distance_formatted": "900 m"
},
{
"links": {
"self": "https://www.allovoisins.com/s/8654097"
},
"budget": 0,
"ref_id": 8654097,
"datetime": "2023-11-28 14:56:02",
"duration": 1,
"end_date": null,
"latitude": 47.2182,
"only_pro": false,
"ref_type": "search",
"card_type": "card_search_public",
"city_name": "Nantes",
"longitude": -1.55947,
"object_id": 5392,
"start_date": null,
"category_id": 124,
"description": "Bonjour, Je cherche une personne qui pourrait me monter cette écran avec caméra intégrée à l'arrière du véhicule je suis livre aujourd'hui , je vie prêt de leclerc paridise à Nantes. Au plaisir de vous lire Merci. Cordialement Sal",
"object_name": "Bricolage - Petits travaux",
"ref_type_id": 101,
"search_type": 4,
"card_type_id": 301,
"district_name": "Bretagne",
"duration_type": 3,
"relationships": {
"moment": null,
"social": {
"type": "social",
"answerers_count": 2,
"likes_count": 0,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8654097?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
},
"leaseholder": {
"id": 5508536,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar6.png",
"is_favorite": false,
"is_new_user": true,
"display_name": "Sam F.",
"user_ratings": 0,
"part_pro_status": 0,
"user_ratings_count": 0
}
},
"budget_formatted": "À convenir",
"duration_formatted": "",
"location_formatted": "Nantes (Bretagne)",
"search_picture_url": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg",
"search_picture_urls": [
{
"l": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg",
"s": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg"
}
],
"is_category_regulated": false,
"search_pictures_count": 1,
"published_at_formatted": "postée le 28 nov.",
"published_at_formatted_year": "demande postée le 28 nov. 2023",
"distance_formatted": "1000 m"
}
]
}

View File

@@ -0,0 +1,311 @@
{
"format": "json",
"data": {
"ref_type_id": 101,
"ref_id": 8654097,
"type": "search",
"category_id": 124,
"category_slug": "bricolage-petits-travaux",
"object_id": 5392,
"object_name": "Bricolage - Petits travaux",
"description": "Bonjour, Je cherche une personne qui pourrait me monter cette écran avec caméra intégrée à l'arrière du véhicule je suis livre aujourd'hui , je vie prêt de leclerc paridise à Nantes. Au plaisir de vous lire Merci. Cordialement Sal",
"search_type": 4,
"status": 0,
"start_date": null,
"end_date": null,
"latitude": 47.2182,
"longitude": -1.55947,
"budget": 0,
"duration": 1,
"duration_type": 3,
"is_private_search": false,
"only_pro": false,
"is_category_regulated": false,
"budget_formatted": "À convenir",
"duration_formatted": "",
"location_formatted": "Nantes (Bretagne)",
"distance_formatted": "1000 m",
"published_at_formatted": "le 28 nov. 2023 à 14:56",
"pictures": [
{
"type": "search_picture",
"id": 9642349,
"picture_urls": {
"large": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg",
"small": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_s.jpg"
}
}
],
"relationships": {
"moment": null,
"leaseholder": {
"id": 5508536,
"type": "user",
"is_pro": false,
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar6.png",
"is_favorite": false,
"is_new_user": true,
"display_name": "Sam F.",
"user_ratings": 0,
"part_pro_status": 0,
"user_ratings_count": 0,
"profile_url": "https://www.allovoisins.com/p/samfalko"
},
"offerers_users": [
{
"card_type_id": 351,
"card_type": "card_user",
"ref_type_id": 102,
"ref_id": 5049288,
"first_name": "Noah",
"display_name": "Noah C.",
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar8.png",
"reviews_count": 3,
"average_rating": 4,
"online_latest_activity_at": 12,
"online_latest_activity_at_formatted": "En ligne il y a 12 minutes",
"distance_formatted": "3,6 km",
"location_formatted": "Saint-Sébastien-sur-Loire (Centre)",
"full_location_formatted": "Saint-Sébastien-sur-Loire (Centre)",
"presentation": "Je suis un jeune sportif, dynamiques, je fait de la peinture et je cherche des petit chantiers pour me faire un peu de sous avec plaisir",
"headline": "Noah",
"part_pro_status": 0,
"is_independent": false,
"user_url": "https://www.allovoisins.com/p/noahcatel",
"is_vau": false,
"is_new_user": false,
"is_favorite": false,
"is_available_now": false,
"mobile_phone": null,
"can_report_user": true,
"relationships": {
"gallery_pictures": [
{
"id": 956086,
"name": "Menuiserie - Huisserie - Agencement",
"type": "gallery_picture",
"image": "https://static.allovoisins.com/uploads/u/galleries/e/f/9/ef91ac28a8_956086_l.jpg",
"ref_id": 956086,
"user_id": 5049288,
"object_id": 5402,
"image_full": "https://static.allovoisins.com/uploads/u/galleries/e/f/9/ef91ac28a8_956086_l.jpg",
"is_service": true,
"category_id": 134,
"description": "Volet à corde ",
"image_large": "https://static.allovoisins.com/uploads/u/galleries/e/f/9/ef91ac28a8_956086_l.jpg",
"image_small": "https://static.allovoisins.com/uploads/u/galleries/e/f/9/ef91ac28a8_956086_s.jpg",
"object_name": "Menuiserie - Huisserie - Agencement",
"ref_type_id": 106,
"category_url": "https://www.allovoisins.com/offreurs/menuiserie-huisserie-agencement/saint-sebastien-sur-loire",
"hidden_by_bo": null,
"picture_urls": {
"large": "https://static.allovoisins.com/uploads/u/galleries/e/f/9/ef91ac28a8_956086_l.jpg",
"small": "https://static.allovoisins.com/uploads/u/galleries/e/f/9/ef91ac28a8_956086_s.jpg"
},
"category_type": 2,
"relationships": {
"user": {
"type": "user",
"user_id": 5049288,
"user_url": "https://www.allovoisins.com/p/noahcatel",
"city_name": "Saint-Sébastien-sur-Loire",
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar8.png",
"first_name": "Noah",
"display_name": "Noah C.",
"user_ratings": 4,
"district_name": "Centre",
"is_independent": false,
"part_pro_status": 0,
"location_formatted": "Saint-Sébastien-sur-Loire (Centre)",
"user_ratings_count": 3
}
},
"date_formatted": "Il y a 1 mois"
},
{
"id": 935607,
"name": "Peinture - Tapisserie",
"type": "gallery_picture",
"image": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg",
"ref_id": 935607,
"user_id": 5049288,
"object_id": 5403,
"image_full": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg",
"is_service": true,
"category_id": 135,
"description": "Peinture intérieur ",
"image_large": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg",
"image_small": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_s.jpg",
"object_name": "Peinture - Tapisserie",
"ref_type_id": 106,
"category_url": "https://www.allovoisins.com/offreurs/peinture-tapisserie/saint-sebastien-sur-loire",
"hidden_by_bo": null,
"picture_urls": {
"large": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_l.jpg",
"small": "https://static.allovoisins.com/uploads/u/galleries/b/4/f/b4f40a289d_935607_s.jpg"
},
"category_type": 2,
"relationships": {
"user": {
"type": "user",
"user_id": 5049288,
"user_url": "https://www.allovoisins.com/p/noahcatel",
"city_name": "Saint-Sébastien-sur-Loire",
"avatar_url": "https://static.allovoisins.com/assets/default_avatars/100/Avatar8.png",
"first_name": "Noah",
"display_name": "Noah C.",
"user_ratings": 4,
"district_name": "Centre",
"is_independent": false,
"part_pro_status": 0,
"location_formatted": "Saint-Sébastien-sur-Loire (Centre)",
"user_ratings_count": 3
}
},
"date_formatted": "Il y a 2 mois"
}
]
},
"meta": {
"messaging_channel_id": 35243121,
"answered_at_formatted": "Réponse envoyée le 28 nov. 2023"
}
},
{
"card_type_id": 351,
"card_type": "card_user",
"ref_type_id": 102,
"ref_id": 5442223,
"first_name": "Djamel",
"display_name": "Djamel C.",
"avatar_url": "https://static.allovoisins.com/uploads/u/avatars/b/5/7/b57378b7b7_5442223_m.jpg",
"reviews_count": 10,
"average_rating": 4.5,
"online_latest_activity_at": 11,
"online_latest_activity_at_formatted": "En ligne il y a 11 minutes",
"distance_formatted": "5,4 km",
"location_formatted": "Saint-Herblain (Village Expo)",
"full_location_formatted": "Saint-Herblain (Village Expo)",
"presentation": "Ingénieur en informatique.\nInstallateur de panneaux photovoltaïques.\nConception de site web.\nDigital marketing.\nDesign flyer",
"headline": "Ingénieur en informatique,",
"part_pro_status": 0,
"is_independent": false,
"user_url": "https://www.allovoisins.com/p/djamelchebbah",
"is_vau": false,
"is_new_user": false,
"is_favorite": false,
"is_available_now": false,
"mobile_phone": null,
"can_report_user": true,
"relationships": {
"gallery_pictures": [
{
"id": 942328,
"name": "Installation électrique",
"type": "gallery_picture",
"image": "https://static.allovoisins.com/uploads/u/galleries/2/1/9/2194765440_942328_l.jpg",
"ref_id": 942328,
"user_id": 5442223,
"object_id": 5400,
"image_full": "https://static.allovoisins.com/uploads/u/galleries/2/1/9/2194765440_942328_l.jpg",
"is_service": true,
"category_id": 132,
"description": "Panneaux photovoltaïques ",
"image_large": "https://static.allovoisins.com/uploads/u/galleries/2/1/9/2194765440_942328_l.jpg",
"image_small": "https://static.allovoisins.com/uploads/u/galleries/2/1/9/2194765440_942328_s.jpg",
"object_name": "Installation électrique",
"ref_type_id": 106,
"category_url": "https://www.allovoisins.com/offreurs/installation-electrique/saint-herblain",
"hidden_by_bo": null,
"picture_urls": {
"large": "https://static.allovoisins.com/uploads/u/galleries/2/1/9/2194765440_942328_l.jpg",
"small": "https://static.allovoisins.com/uploads/u/galleries/2/1/9/2194765440_942328_s.jpg"
},
"category_type": 2,
"relationships": {
"user": {
"type": "user",
"user_id": 5442223,
"user_url": "https://www.allovoisins.com/p/djamelchebbah",
"city_name": "Saint-Herblain",
"avatar_url": "https://static.allovoisins.com/uploads/u/avatars/b/5/7/b57378b7b7_5442223_m.jpg",
"first_name": "Djamel",
"display_name": "Djamel C.",
"user_ratings": 4.5,
"district_name": "Village Expo",
"is_independent": false,
"part_pro_status": 0,
"location_formatted": "Saint-Herblain (Village Expo)",
"user_ratings_count": 10
}
},
"date_formatted": "Il y a 1 mois"
},
{
"id": 942318,
"name": "Installation électrique",
"type": "gallery_picture",
"image": "https://static.allovoisins.com/uploads/u/galleries/e/6/b/e6b5265751_942318_l.jpg",
"ref_id": 942318,
"user_id": 5442223,
"object_id": 5400,
"image_full": "https://static.allovoisins.com/uploads/u/galleries/e/6/b/e6b5265751_942318_l.jpg",
"is_service": true,
"category_id": 132,
"description": "Installation et entretien des kit de panneaux solaires (PV) ",
"image_large": "https://static.allovoisins.com/uploads/u/galleries/e/6/b/e6b5265751_942318_l.jpg",
"image_small": "https://static.allovoisins.com/uploads/u/galleries/e/6/b/e6b5265751_942318_s.jpg",
"object_name": "Installation électrique",
"ref_type_id": 106,
"category_url": "https://www.allovoisins.com/offreurs/installation-electrique/saint-herblain",
"hidden_by_bo": null,
"picture_urls": {
"large": "https://static.allovoisins.com/uploads/u/galleries/e/6/b/e6b5265751_942318_l.jpg",
"small": "https://static.allovoisins.com/uploads/u/galleries/e/6/b/e6b5265751_942318_s.jpg"
},
"category_type": 2,
"relationships": {
"user": {
"type": "user",
"user_id": 5442223,
"user_url": "https://www.allovoisins.com/p/djamelchebbah",
"city_name": "Saint-Herblain",
"avatar_url": "https://static.allovoisins.com/uploads/u/avatars/b/5/7/b57378b7b7_5442223_m.jpg",
"first_name": "Djamel",
"display_name": "Djamel C.",
"user_ratings": 4.5,
"district_name": "Village Expo",
"is_independent": false,
"part_pro_status": 0,
"location_formatted": "Saint-Herblain (Village Expo)",
"user_ratings_count": 10
}
},
"date_formatted": "Il y a 1 mois"
}
]
},
"meta": {
"messaging_channel_id": 35243318,
"answered_at_formatted": "Réponse envoyée le 28 nov. 2023"
}
}
],
"contacted_users": [],
"recommended_users": [],
"social": {
"type": "social",
"answerers_count": 2,
"likes_count": 0,
"shares_count": 0,
"recommendations_count": 0,
"user_has_liked": false,
"user_has_shared": false,
"user_has_reported": false,
"share_link": "https://www.allovoisins.com/s/8654097?utm_source=product_transactionnel&utm_medium=share&utm_campaign=search_details",
"comments_count": null,
"comments": null
}
}
}
}

View File

@@ -0,0 +1,25 @@
//
// NotFoundScreen.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
struct NotFoundScreen: View {
var body: some View {
ZStack {
VStack {
Spacer()
Image("oups")
.resizable()
.scaledToFit()
Text("L'annonce à laquelle vous essayez d'accéder est introuvable…")
.bold(16)
Spacer()
}
}
.background(Color.white)
}
}

View File

@@ -0,0 +1,50 @@
//
// OfferDetailsScreen.swift
// AlloVictor
//
// Created by Bodinaud Victor on 14/04/2024.
//
import SwiftUI
struct OfferDetailsScreen: View {
@Environment(\.dismiss) var dismiss
let offerDetails: Offer?
var body: some View {
VStack {
if offerDetails != nil {
OfferDetailsView(offerDetails: offerDetails!)
} else {
NotFoundScreen()
}
}
.navigationBarBackButtonHidden()
.toolbar(content: {
ToolbarItem(placement: .navigation) {
Button(action: {
dismiss()
}, label: {
Image(systemName: "arrow.backward")
.resizable()
.foregroundStyle(Color.black)
.aspectRatio(contentMode: .fill)
.frame(width: 15, height: 15)
})
}
ToolbarItem(placement: .principal) {
Text("Demande publique")
.bold(16)
}
if offerDetails != nil {
ToolbarItem(placement: .topBarTrailing) {
ShareView(link: offerDetails!.relationships.social?.shareLink ?? "")
}
}
})
}
}

View File

@@ -0,0 +1,56 @@
//
// OffersListScreen.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import SwiftUI
struct OffersListScreen: View {
@EnvironmentObject private var viewModel: AlloVictorViewModel
var body: some View {
ScrollView {
LazyVStack {
ForEach(viewModel.offersList) { offer in
if offer.cardType == .publicSearch {
OfferListView(offer: offer, offerDetails: viewModel.offerDetails[offer.id])
} else if offer.cardType == .alloFlash {
AlloFlashView(offer: offer)
}
}
}
}
.background(Color.neutral20)
.toolbar(content: {
ToolbarItem(placement: .topBarLeading) {
Button(action: {}, label: {
AvatarView(avatarUrl: "", width: 35, height: 35)
})
}
ToolbarItem(placement: .principal) {
VStack {
Image("SimpleLogo")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 25)
Text("Nantes (Procès)")
.medium(12)
.foregroundStyle(Color.gray)
}
}
ToolbarItem(placement: .topBarTrailing) {
Button(action: {}, label: {
Image(systemName: "bell")
})
.foregroundColor(.black)
}
})
.navigationBarTitleDisplayMode(.inline)
.toolbarBackground(.white, for: .navigationBar)
.toolbarBackground(.visible, for: .navigationBar)
}
}

View File

@@ -0,0 +1,26 @@
//
// ShowFullPictureScreen.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
import CachedAsyncImage
struct ShowFullPictureScreen: View {
let pictureUrl: String
var body: some View {
VStack(alignment: .trailing) {
CachedAsyncImage(url: URL(string: pictureUrl)) { image in
image
.resizable()
.scaledToFit()
} placeholder: {
ProgressView()
}
}
}
}

View File

@@ -0,0 +1,17 @@
//
// Constants.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import Foundation
struct Constants {
public static let baseUrl = "https://git.mahtan-melwasul.com/Mahtan/AlloVictor/raw/branch/develop/AlloVictor/Resources"
struct Urls {
static let list = URL(string: "\(baseUrl)/Screen1.json")!
static let detail = URL(string: "\(baseUrl)/Screen2.json")!
}
}

View File

@@ -0,0 +1,74 @@
//
// HTTPClient.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import Foundation
enum NetworkError: Error {
case badRequest
case invalideResponse
case failedDecoding
}
enum HTTPMethod {
case get
var name: String {
switch self {
case .get:
return "GET"
}
}
}
struct Resource<T: Codable> {
let url: URL
var method: HTTPMethod = .get
var modelType: T.Type
}
struct HTTPClient {
private var defaultHeaders: [String: String] {
let headers = ["Content-Type": "application/json"]
return headers
}
public func load<T: Codable>(_ resource: Resource<T>) async throws -> T {
var request = URLRequest(url: resource.url)
switch resource.method {
case .get:
let components = URLComponents(url: resource.url, resolvingAgainstBaseURL: false)
guard let url = components?.url else {
throw NetworkError.badRequest
}
request = URLRequest(url: url)
}
let configuration = URLSessionConfiguration.default
configuration.httpAdditionalHeaders = defaultHeaders
let session = URLSession(configuration: configuration)
let (data, response) = try await session.data(for: request)
guard let _ = response as? HTTPURLResponse else {
throw NetworkError.invalideResponse
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
guard let result = try?
decoder.decode(resource.modelType, from: data) else {
throw NetworkError.failedDecoding
}
return result
}
}

View File

@@ -0,0 +1,26 @@
//
// AlloVictorViewModel.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import Foundation
@MainActor
class AlloVictorViewModel: ObservableObject {
@Published var offersList: [Offer] = []
@Published var offerDetails: [Int: Offer] = [:]
let httpClient = HTTPClient()
func getDatas() async throws {
let listResource = Resource(url: Constants.Urls.list, modelType: OfferListResponseDTO.self)
let detailsResource = Resource(url: Constants.Urls.detail, modelType: OfferDetailsResponseDTO.self)
offersList = try await httpClient.load(listResource).data
let offer = try await httpClient.load(detailsResource).data
offerDetails[offer.id] = offer
}
}

View File

@@ -0,0 +1,58 @@
//
// AlloFlashView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import SwiftUI
import CachedAsyncImage
struct AlloFlashView: View {
@State private var isLiked = false
let offer: Offer
var body: some View {
VStack {
VStack(alignment: .leading) {
HStack {
Image("Icon")
.resizable()
.frame(width: 25, height: 25)
.aspectRatio(contentMode: .fit)
Text("AlloFlash")
.medium(13)
}
Divider()
}
.padding([.leading, .trailing])
CachedAsyncImage(url: URL(string: offer.sectionBackgroundImage ?? "")) { image in
image
.resizable()
.aspectRatio(contentMode: .fit)
} placeholder: {
ProgressView()
}
VStack(alignment: .leading) {
HStack {
Text("\(offer.relationships.social?.likesCount ?? 0) j'aime")
.regular(12)
}
Divider()
Button(action: {
isLiked.toggle()
}, label: {
HStack {
Image(systemName: isLiked ? "heart.fill" : "heart")
.foregroundStyle(isLiked ? Color.red : Color.black)
Text("J'aime")
.medium(14)
}
})
}
.padding([.leading, .trailing, .bottom])
}
.buttonStyle(PlainButtonStyle())
.background(Color.white)
}
}

View File

@@ -0,0 +1,31 @@
//
// AvatarView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 15/04/2024.
//
import SwiftUI
import CachedAsyncImage
struct AvatarView: View {
let avatarUrl: String
let width: CGFloat
let height: CGFloat
var body: some View {
CachedAsyncImage(url: URL(string: avatarUrl)) { image in
image
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
.clipShape(Circle())
} placeholder: {
Image("Avatar")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: width, height: height)
.clipShape(Circle())
}
}
}

View File

@@ -0,0 +1,45 @@
//
// OfferBodyView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
import CachedAsyncImage
struct OfferBodyView: View {
let offer: Offer
var body: some View {
HStack(alignment: .top) {
AvatarView(avatarUrl: offer.relationships.leaseholder?.avatarUrl ?? "", width: 50, height: 50)
VStack(alignment: .leading, spacing: 8) {
Text(offer.relationships.leaseholder?.displayName ?? "")
.demiBold(16)
Text(offer.desc ?? "")
.regular(16)
if offer.searchPictureUrl != nil {
CachedAsyncImage(url: URL(string: offer.searchPictureUrl!)) { image in
image
.resizable()
.cornerRadius(8)
.scaledToFit()
} placeholder: {
ProgressView()
.padding()
}
}
VStack(alignment: .leading, spacing: 4) {
Text("\(offer.locationFormatted ?? "") - \(offer.distanceFormatted ?? "")")
.regular(12)
Text("Budget: \(offer.budgetFormatted ?? "")")
.regular(12)
}
}
}
}
}

View File

@@ -0,0 +1,24 @@
//
// OfferHeaderView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
struct OfferHeaderView: View {
let publishedAt: String
var body: some View {
HStack {
Image(systemName: "globe.americas.fill")
.foregroundStyle(Color.black)
Text("Demande publique")
.medium(13)
Spacer()
Text(publishedAt)
.regular(12)
}
}
}

View File

@@ -0,0 +1,54 @@
//
// OfferSocialView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 14/04/2024.
//
import SwiftUI
struct OfferSocialView: View {
@State private var isLiked = false
let social: Social
var body: some View {
VStack(spacing: 8) {
HStack {
Text("\(social.likesCount) j'aime")
.regular(12)
Spacer()
Text("\(social.answerersCount ?? 0) réponses")
.regular(12)
}
Divider()
HStack {
Button(action: {
isLiked.toggle()
}, label: {
Image(systemName: isLiked ? "heart.fill" : "heart")
.foregroundStyle(isLiked ? Color.red : Color.black)
Text("J'aime")
.medium(14)
})
Spacer()
Button(action: {}, label: {
Image(systemName: "person.3")
.foregroundStyle(Color.black)
Text("Recommander")
.medium(14)
})
Spacer()
Button(action: {}, label: {
Image(systemName: "ellipsis.message")
.foregroundStyle(Color.black)
Text("Répondre")
.medium(14)
})
}
.buttonStyle(PlainButtonStyle())
}
.padding()
}
}

View File

@@ -0,0 +1,21 @@
//
// OfferDetailsAwnserCountView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
struct OfferDetailsAwnserCountView: View {
let awnserCount: Int
var body: some View {
HStack {
Image(systemName: "ellipsis.message")
Text("\(awnserCount) offreurs ont répondu")
}
.bold(18)
.padding([.leading, .trailing])
}
}

View File

@@ -0,0 +1,61 @@
//
// OfferDetailsBodyView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
import MapKit
struct OfferDetailsBodyView: View {
let offerDetails: Offer
var body: some View {
VStack {
HStack(alignment: .top) {
AvatarView(avatarUrl: offerDetails.relationships.leaseholder?.avatarUrl ?? "", width: 50, height: 50)
VStack(alignment: .leading, spacing: 8) {
HStack {
if offerDetails.relationships.leaseholder != nil {
OfferDetailsLeaseholderInfosView(leaseholder: offerDetails.relationships.leaseholder!)
}
Spacer()
VStack(alignment: .trailing) {
Text("demande postée")
.medium(12)
Text(offerDetails.publishedAtFormatted ?? "")
.medium(12)
}
}
Text(offerDetails.desc ?? "")
.regular(16)
if offerDetails.pictures != nil {
OfferDetailsGalleryView(pictures: offerDetails.pictures!)
}
OfferDetailsMapView(latitude: offerDetails.latitude!, longitude: offerDetails.longitude!)
.frame(height: 150)
.cornerRadius(8)
VStack(alignment: .leading, spacing: 4) {
Text("\(offerDetails.locationFormatted!) - \(offerDetails.distanceFormatted!)")
.regular(12)
Text("Budget: \(offerDetails.budgetFormatted!)")
.regular(12)
Text("Catégorie : \(offerDetails.objectName!)")
.regular(12)
}
}
}
.padding([.leading, .trailing])
OfferSocialView(social: offerDetails.relationships.social!)
}
}
}

View File

@@ -0,0 +1,35 @@
//
// OfferDetailsGalleryView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
import CachedAsyncImage
struct OfferDetailsGalleryView: View {
@State var showFullScreenPicture = false
let pictures: [OfferPicture]
var body: some View {
ForEach(pictures) { picture in
CachedAsyncImage(url: URL(string: picture.pictureUrls.large)) { image in
image
.resizable()
.cornerRadius(8)
.scaledToFit()
} placeholder: {
ProgressView()
.padding()
}
.sheet(isPresented: $showFullScreenPicture, content: {
ShowFullPictureScreen(pictureUrl: picture.pictureUrls.large)
})
.onTapGesture {
showFullScreenPicture.toggle()
}
}
}
}

View File

@@ -0,0 +1,26 @@
//
// OfferDetailsLeaseholderInfosView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
struct OfferDetailsLeaseholderInfosView: View {
var leaseholder: Leaseholder
var body: some View {
VStack(alignment: .leading) {
Text(leaseholder.displayName)
.demiBold(16)
HStack {
Image(systemName: "star.fill")
.foregroundStyle(Color.neutral20)
Text("\(leaseholder.userRatings == 0 ? "-" : "\(leaseholder.userRatings)")/5")
.bold(14)
}
.regular(12)
}
}
}

View File

@@ -0,0 +1,32 @@
//
// OfferDetailsMapView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
import MapKit
struct OfferDetailsMapView: View {
let latitude: Double
let longitude: Double
var body: some View {
Map(bounds: MapCameraBounds(minimumDistance: 8000), interactionModes: []) {
Annotation("", coordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude)) {
AvatarView(avatarUrl: "", width: 40, height: 40)
}
}
.mapStyle(
.standard(
pointsOfInterest: .excludingAll,
showsTraffic: false
)
)
}
}
#Preview {
OfferDetailsMapView(latitude: 47.2182, longitude: -1.55947)
}

View File

@@ -0,0 +1,31 @@
//
// OffererUserGallery.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
import CachedAsyncImage
struct OffererUserGallery: View {
let gallery: [GalleryPicture]
var body: some View {
ScrollView(.horizontal) {
HStack {
ForEach(gallery) { picture in
CachedAsyncImage(url: URL(string: picture.imageSmall)) { image in
image
.resizable()
.frame(width: 200, height: 100)
.scaledToFill()
} placeholder: {
ProgressView()
}
}
}
}
.scrollIndicators(.hidden)
}
}

View File

@@ -0,0 +1,30 @@
//
// OffererUserInfos.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
struct OffererUserInfos: View {
let offererUser: OfferersUser
var body: some View {
VStack(alignment: .leading) {
HStack {
AvatarView(avatarUrl: offererUser.avatarUrl, width: 65, height: 65)
VStack(alignment: .leading) {
Text(offererUser.displayName)
.medium(15)
Text(offererUser.headline)
.medium(12)
Text("\(offererUser.locationFormatted) - à \(offererUser.distanceFormatted)")
.light(12)
Text(offererUser.onlineLatestActivityAtFormatted)
.light(12)
}
}
}
}
}

View File

@@ -0,0 +1,20 @@
//
// OffererUserProStatusView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
struct OffererUserProStatusView: View {
let isIndependent: Bool
var body: some View {
Text(isIndependent ? "Auto-entrepreneur" : "Particulier")
.demiBold(12)
.padding(4)
.background(isIndependent ? Color.grape30 : Color.neutral20)
.cornerRadius(5)
}
}

View File

@@ -0,0 +1,24 @@
//
// OffererUserRatingView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 18/04/2024.
//
import SwiftUI
struct OffererUserRatingView: View {
let averageRating: Double
let reviewsCount: Int
var body: some View {
HStack {
Image(systemName: "star.fill")
.foregroundStyle(Color.yellow)
Text("\(String(format: "%.1f", averageRating))/5")
.demiBold(18)
Text("(\(reviewsCount) avis)")
.bold(14)
}
}
}

View File

@@ -0,0 +1,25 @@
//
// ShareView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 14/04/2024.
//
import SwiftUI
struct ShareView: View {
let link: String
var body: some View {
HStack {
ShareLink(item: URL(string: link)!) {
Image(systemName: "square.and.arrow.up")
}
.foregroundColor(.black)
Button(action: {}, label: {
Image(systemName: "ellipsis.circle")
})
.foregroundColor(.black)
}
}
}

View File

@@ -0,0 +1,89 @@
//
// TextModifier.swift
// AlloVictor
//
// Created by Bodinaud Victor on 14/04/2024.
//
import Foundation
import SwiftUI
struct AlloTextExtraLight: ViewModifier {
let size: CGFloat
func body(content: Content) -> some View {
content
.font(.custom("TTChocolates-ExtraLight", size: size))
}
}
struct AlloTextLight: ViewModifier {
let size: CGFloat
func body(content: Content) -> some View {
content
.font(.custom("TTChocolates-Light", size: size))
}
}
struct AlloTextRegular: ViewModifier {
let size: CGFloat
func body(content: Content) -> some View {
content
.font(.custom("TTChocolates-Regular", size: size))
}
}
struct AlloTextMedium: ViewModifier {
let size: CGFloat
func body(content: Content) -> some View {
content
.font(.custom("TTChocolates-Medium", size: size))
}
}
struct AlloTextDemiBold: ViewModifier {
let size: CGFloat
func body(content: Content) -> some View {
content
.font(.custom("TTChocolates-DemiBold", size: size))
}
}
struct AlloTextBold: ViewModifier {
let size: CGFloat
func body(content: Content) -> some View {
content
.font(.custom("TTChocolates-Bold", size: size))
}
}
extension View {
func extraLight(_ size: CGFloat) -> some View {
modifier(AlloTextExtraLight(size: size))
}
func light(_ size: CGFloat) -> some View {
modifier(AlloTextLight(size: size))
}
func regular(_ size: CGFloat) -> some View {
modifier(AlloTextRegular(size: size))
}
func medium(_ size: CGFloat) -> some View {
modifier(AlloTextMedium(size: size))
}
func demiBold(_ size: CGFloat) -> some View {
modifier(AlloTextDemiBold(size: size))
}
func bold(_ size: CGFloat) -> some View {
modifier(AlloTextBold(size: size))
}
}

View File

@@ -0,0 +1,50 @@
//
// OfferDetailsView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 14/04/2024.
//
import SwiftUI
import MapKit
struct OfferDetailsView: View {
let offerDetails: Offer
var body: some View {
ScrollView {
LazyVStack(alignment: .leading) {
OfferDetailsBodyView(offerDetails: offerDetails)
OfferDetailsAwnserCountView(awnserCount: offerDetails.relationships.social?.answerersCount ?? 0)
ForEach(offerDetails.relationships.offerersUsers!) { offererUser in
OffererUserView(offererUser: offererUser)
.padding()
}
}
}
.background(Color.white)
.toolbar {
ToolbarItemGroup(placement: .bottomBar) {
HStack(alignment: .center) {
Button(action: {}, label: {
HStack {
Image(systemName: "ellipsis.message")
.foregroundStyle(Color.white)
Text("Répondre")
.bold(14)
.foregroundStyle(Color.white)
}
})
.padding([.top, .bottom], 4)
.padding([.leading, .trailing], 16)
.background(Color.pillButton)
.clipShape(Capsule())
.foregroundStyle(Color.white)
}
}
}
.toolbarColorScheme(.light)
}
}

View File

@@ -0,0 +1,33 @@
//
// OfferListView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 13/04/2024.
//
import SwiftUI
import CachedAsyncImage
struct OfferListView: View {
let offer: Offer
let offerDetails: Offer?
var body: some View {
VStack {
NavigationLink(value: Route.detail(offerDetails)) {
VStack {
OfferHeaderView(publishedAt: offer.publishedAtFormatted ?? "")
Divider()
OfferBodyView(offer: offer)
}
}
.padding()
.buttonStyle(PlainButtonStyle())
OfferSocialView(social: offer.relationships.social!)
}
.background(Color.white)
}
}

View File

@@ -0,0 +1,36 @@
//
// OffererUserView.swift
// AlloVictor
//
// Created by Bodinaud Victor on 14/04/2024.
//
import SwiftUI
struct OffererUserView: View {
let offererUser: OfferersUser
var body: some View {
VStack(alignment: .trailing) {
VStack(alignment: .trailing) {
OffererUserProStatusView(isIndependent: offererUser.isIndependent)
VStack(alignment: .leading) {
OffererUserInfos(offererUser: offererUser)
.padding([.leading, .trailing])
if offererUser.relationships.galleryPictures != nil {
OffererUserGallery(gallery: offererUser.relationships.galleryPictures!)
}
OffererUserRatingView(averageRating: offererUser.averageRating, reviewsCount: offererUser.reviewsCount)
.padding()
}
}
.background(Color.white)
.addBorder(Color.neutral20, cornerRadius: 5)
Text(offererUser.meta.answeredAtFormatted)
.regular(12)
}
}
}