├── .nvmrc ├── .eslintignore ├── src ├── routes │ ├── GroupExplorer │ │ ├── GroupExplorer.scss │ │ ├── index.js │ │ ├── GroupSearch │ │ │ └── index.js │ │ ├── ExplorerBanner │ │ │ └── index.js │ │ └── GroupViewFilter │ │ │ ├── index.js │ │ │ └── GroupViewFilter.scss │ ├── AuthLayoutRouter │ │ ├── components │ │ │ ├── Sidebar │ │ │ │ ├── component.scss │ │ │ │ └── index.js │ │ │ ├── TopNav │ │ │ │ ├── TopNavDropdown │ │ │ │ │ ├── TopNavDropdown.store.js │ │ │ │ │ └── index.js │ │ │ │ ├── NoItems │ │ │ │ │ ├── index.js │ │ │ │ │ ├── NoItems.js │ │ │ │ │ └── NoItems.scss │ │ │ │ ├── LoadingItems │ │ │ │ │ ├── index.js │ │ │ │ │ └── LoadingItems.scss │ │ │ │ ├── LocaleDropdown │ │ │ │ │ └── index.js │ │ │ │ ├── index.js │ │ │ │ ├── MessagesDropdown │ │ │ │ │ └── index.js │ │ │ │ └── NotificationsDropdown │ │ │ │ │ └── index.js │ │ │ ├── Drawer │ │ │ │ └── index.js │ │ │ ├── SiteTour │ │ │ │ └── index.js │ │ │ └── Navigation │ │ │ │ ├── NavLink │ │ │ │ └── index.js │ │ │ │ ├── index.js │ │ │ │ └── TopicNavigation │ │ │ │ └── index.js │ │ └── index.js │ ├── OAuth │ │ ├── Login │ │ │ ├── index.js │ │ │ ├── Login.store.js │ │ │ └── Login.test.js │ │ └── Consent │ │ │ ├── index.js │ │ │ ├── Consent.test.js │ │ │ └── Consent.store.js │ ├── JoinGroup │ │ └── index.js │ ├── Messages │ │ ├── Header │ │ │ └── index.js │ │ ├── Message │ │ │ └── index.js │ │ ├── MessageForm │ │ │ └── index.js │ │ ├── CloseMessages │ │ │ ├── index.js │ │ │ ├── CloseMessages.js │ │ │ └── CloseMessages.scss │ │ ├── MessageSection │ │ │ └── index.js │ │ ├── PeopleSelector │ │ │ ├── index.js │ │ │ ├── PeopleList │ │ │ │ └── index.js │ │ │ ├── PeopleListItem │ │ │ │ ├── index.js │ │ │ │ ├── PeopleListItem.test.js │ │ │ │ └── __snapshots__ │ │ │ │ │ └── PeopleListItem.test.js.snap │ │ │ └── MatchingPeopleListItem │ │ │ │ ├── index.js │ │ │ │ └── __snapshots__ │ │ │ │ └── MatchingPeopleListItem.test.js.snap │ │ ├── index.js │ │ └── ThreadList │ │ │ └── index.js │ ├── RootRouter │ │ └── index.js │ ├── ChatRoom │ │ ├── ChatPost │ │ │ └── index.js │ │ └── index.js │ ├── MapExplorer │ │ ├── MapDrawer │ │ │ └── index.js │ │ ├── SavedSearches │ │ │ └── index.js │ │ └── index.js │ ├── NonAuthLayoutRouter │ │ ├── Login │ │ │ ├── index.js │ │ │ └── Login.test.js │ │ ├── Signup │ │ │ ├── index.js │ │ │ ├── VerifyEmail │ │ │ │ ├── index.js │ │ │ │ └── VerifyEmail.test.js │ │ │ ├── FinishRegistration │ │ │ │ └── index.js │ │ │ ├── Signup.store.test.js │ │ │ └── Signup.test.js │ │ ├── index.js │ │ ├── ManageNotifications │ │ │ ├── index.js │ │ │ └── ManageNotifications.scss │ │ ├── PasswordReset │ │ │ ├── index.js │ │ │ ├── PasswordReset.connector.js │ │ │ └── PasswordReset.test.js │ │ └── NonAuthLayoutRouter.test.js │ ├── GroupWelcomeModal │ │ ├── index.js │ │ └── __snapshots__ │ │ │ └── GroupWelcomeModal.js.snap │ ├── PublicLayoutRouter │ │ └── index.js │ ├── WelcomeWizardRouter │ │ ├── index.js │ │ ├── AddLocation │ │ │ ├── index.js │ │ │ ├── AddLocation.test.js │ │ │ └── AddLocation.connector.test.js │ │ ├── UploadPhoto │ │ │ ├── index.js │ │ │ ├── __snapshots__ │ │ │ │ └── UploadPhoto.test.js.snap │ │ │ ├── UploadPhoto.test.js │ │ │ └── UploadPhoto.connector.test.js │ │ └── WelcomeExplore │ │ │ ├── index.js │ │ │ ├── WelcomeExplore.connector.js │ │ │ └── WelcomeExplore.test.js │ ├── GroupSettings │ │ ├── ExportDataTab │ │ │ ├── index.js │ │ │ └── ExportDataTab.scss │ │ ├── AgreementsTab │ │ │ └── index.js │ │ ├── ResponsibilitiesTab │ │ │ └── index.js │ │ ├── CustomViewsTab │ │ │ └── index.js │ │ ├── PrivacySettingsTab │ │ │ └── index.js │ │ ├── SettingsSection │ │ │ ├── index.js │ │ │ └── SettingsSection.js │ │ ├── DeleteSettingsTab │ │ │ ├── index.js │ │ │ └── DeleteSettingsTab.test.js │ │ ├── GroupSettingsTab │ │ │ └── index.js │ │ ├── ImportExportSettingsTab │ │ │ ├── index.js │ │ │ └── ImportExportSettingsTab.test.js │ │ ├── index.js │ │ ├── RelatedGroupsTab │ │ │ └── index.js │ │ ├── RolesSettingsTab │ │ │ └── index.js │ │ ├── InviteSettingsTab │ │ │ ├── index.js │ │ │ └── InviteSettingsTab.test.js │ │ ├── TopicsSettingsTab │ │ │ └── index.js │ │ └── MembershipRequestsTab │ │ │ └── index.js │ ├── UserSettings │ │ ├── BlockedUsersTab │ │ │ └── index.js │ │ ├── EditProfileTab │ │ │ └── index.js │ │ ├── SavedSearchesTab │ │ │ └── index.js │ │ ├── AccountSettingsTab │ │ │ ├── index.js │ │ │ └── AccountSettingsTab.test.js │ │ ├── PaymentSettingsTab │ │ │ ├── index.js │ │ │ └── PaymentSettingsTab.test.js │ │ ├── NotificationSettingsTab │ │ │ └── index.js │ │ ├── index.js │ │ ├── UserGroupsTab │ │ │ └── index.js │ │ ├── ManageInvitesTab │ │ │ └── index.js │ │ ├── UserSettings.store.test.js │ │ └── __snapshots__ │ │ │ └── UserSettings.connector.test.js.snap │ ├── PostDetail │ │ ├── ProjectContributions │ │ │ └── index.js │ │ ├── index.js │ │ ├── Comments │ │ │ ├── ShowMore.scss │ │ │ ├── Comment │ │ │ │ └── index.js │ │ │ ├── CommentForm │ │ │ │ └── index.js │ │ │ ├── index.js │ │ │ └── ShowMore.js │ │ └── __snapshots__ │ │ │ └── PostDetail.test.js.snap │ ├── Search │ │ └── index.js │ ├── Groups │ │ └── index.js │ ├── Members │ │ └── index.js │ ├── Stream │ │ └── index.js │ ├── Events │ │ ├── index.js │ │ ├── Events.store.test.js │ │ ├── __snapshots__ │ │ │ └── Events.store.test.js.snap │ │ └── Events.store.js │ ├── AllTopics │ │ ├── index.js │ │ ├── AllTopics.store.test.js │ │ └── __snapshots__ │ │ │ └── AllTopics.store.test.js.snap │ ├── GroupDetail │ │ └── index.js │ ├── GroupSidebar │ │ ├── index.js │ │ └── __snapshots__ │ │ │ └── GroupSidebar.connector.test.js.snap │ ├── LandingPage │ │ └── index.js │ ├── MemberProfile │ │ ├── MemberPosts │ │ │ ├── index.js │ │ │ ├── MemberPosts.scss │ │ │ ├── MemberPosts.test.js │ │ │ └── MemberPosts.connector.js │ │ ├── index.js │ │ ├── MemberComments │ │ │ ├── index.js │ │ │ ├── MemberComments.scss │ │ │ ├── MemberComments.test.js │ │ │ └── MemberComments.connector.js │ │ ├── RecentActivity │ │ │ ├── index.js │ │ │ └── RecentActivity.scss │ │ └── MemberVotes │ │ │ ├── MemberVotes.scss │ │ │ ├── index.js │ │ │ └── MemberVotes.test.js │ └── FullPageModal │ │ └── index.js ├── components │ ├── Widget │ │ ├── MapWidget │ │ │ ├── MapWidget.scss │ │ │ ├── index.js │ │ │ └── MapWidget.js │ │ ├── PrivacyWidget │ │ │ ├── Privacy.scss │ │ │ ├── index.js │ │ │ └── PrivacyWidget.js │ │ ├── StewardsWidget │ │ │ ├── StewardsWidget.scss │ │ │ ├── index.js │ │ │ └── StewardsWidget.js │ │ ├── index.js │ │ ├── JoinWidget │ │ │ └── index.js │ │ ├── AtAGlanceWidget │ │ │ ├── index.js │ │ │ └── AtAGlanceWidget.scss │ │ ├── EventsWidget │ │ │ └── index.js │ │ ├── FarmOpenToPublic │ │ │ └── index.js │ │ ├── GroupsWidget │ │ │ └── index.js │ │ ├── RichTextWidget │ │ │ └── index.js │ │ ├── TopicsWidget │ │ │ └── index.js │ │ ├── FarmDetailsWidget │ │ │ └── index.js │ │ ├── FarmMapWidget │ │ │ └── index.js │ │ ├── MembersWidget │ │ │ └── index.js │ │ ├── WelcomeWidget │ │ │ └── index.js │ │ ├── ProjectsWidget │ │ │ └── index.js │ │ ├── GroupTopicsWidget │ │ │ └── index.js │ │ ├── RecentPostsWidget │ │ │ └── index.js │ │ ├── AnnouncementWidget │ │ │ └── index.js │ │ ├── OffersAndRequestsWidget │ │ │ └── index.js │ │ └── OpportunitiesToCollaborateWidget │ │ │ └── index.js │ ├── Map │ │ ├── index.js │ │ └── Map.scss │ ├── Button │ │ ├── index.js │ │ └── __snapshots__ │ │ │ └── Button.test.js.snap │ ├── Pill │ │ └── index.js │ ├── Select │ │ └── index.js │ ├── Switch │ │ ├── index.js │ │ ├── Switch.test.js │ │ ├── Switch.js │ │ └── __snapshots__ │ │ │ └── Switch.test.js.snap │ ├── Avatar │ │ └── index.js │ ├── Badge │ │ ├── index.js │ │ ├── Badge.test.js │ │ ├── __snapshots__ │ │ │ └── Badge.test.js.snap │ │ └── component.js │ ├── CheckBox │ │ ├── index.js │ │ ├── CheckBox.test.js │ │ ├── CheckBox.scss │ │ └── __snapshots__ │ │ │ └── CheckBox.test.js.snap │ ├── EmojiPill │ │ └── index.js │ ├── EmojiRow │ │ ├── index.js │ │ └── EmojiRow.scss │ ├── Loading │ │ ├── index.js │ │ └── Loading.test.js │ ├── Pillbox │ │ ├── index.js │ │ └── Pillbox.test.js │ ├── PostLabel │ │ └── index.js │ ├── Tooltip │ │ ├── index.js │ │ └── Tooltip.scss │ ├── BadgedIcon │ │ ├── index.js │ │ └── component.js │ ├── Dropdown │ │ └── index.js │ ├── EmojiPicker │ │ └── index.js │ ├── FancyLink │ │ └── index.js │ ├── GroupCard │ │ ├── index.js │ │ └── GroupHeader │ │ │ └── index.js │ ├── Highlight │ │ └── index.js │ ├── HyloHTML │ │ ├── index.js │ │ └── HyloHTML.js │ ├── ModalFooter │ │ └── index.js │ ├── ModalSidebar │ │ └── index.js │ ├── PostCard │ │ ├── ChatCard │ │ │ └── index.js │ │ ├── PostBody │ │ │ └── index.js │ │ ├── Feature │ │ │ ├── index.js │ │ │ ├── Feature.scss │ │ │ └── Feature.js │ │ ├── EventBody │ │ │ └── index.js │ │ ├── EventDate │ │ │ ├── index.js │ │ │ ├── EventDate.js │ │ │ └── EventDate.scss │ │ ├── EventRSVP │ │ │ ├── index.js │ │ │ └── EventRSVP.scss │ │ ├── PeopleInfo │ │ │ ├── index.js │ │ │ └── PeopleInfo.scss │ │ ├── PostFooter │ │ │ └── index.js │ │ ├── PostTitle │ │ │ ├── index.js │ │ │ └── __snapshots__ │ │ │ │ └── PostTitle.test.js.snap │ │ ├── PostDetails │ │ │ └── index.js │ │ ├── PostCompletion │ │ │ ├── index.js │ │ │ └── PostCompletion.scss │ │ ├── PostBodyProposal │ │ │ └── index.js │ │ ├── PostHeader │ │ │ ├── index.js │ │ │ └── PostHeader.store.test.js │ │ ├── PostGroups │ │ │ ├── index.js │ │ │ └── PostGroups.connector.js │ │ ├── index.js │ │ ├── __snapshots__ │ │ │ └── PostCard.connector.test.js.snap │ │ └── PostCard.connector.test.js │ ├── QuorumBar │ │ └── index.js │ ├── SkillLabel │ │ ├── index.js │ │ └── component.js │ ├── SwitchStyled │ │ └── index.js │ ├── TagInput │ │ └── index.js │ ├── TextInput │ │ ├── index.js │ │ ├── TextInput.test.js │ │ └── __snapshots__ │ │ │ └── TextInput.test.js.snap │ ├── Affiliation │ │ ├── index.js │ │ └── __snapshots__ │ │ │ └── Affiliation.test.js.snap │ ├── BadgeEmoji │ │ └── index.js │ ├── ClickCatcher │ │ └── index.js │ ├── CreateModal │ │ └── index.js │ ├── DropdownButton │ │ └── index.js │ ├── FarmGroupDetailBody │ │ ├── FarmGroupDetailBody.scss │ │ └── index.js │ ├── GoogleButton │ │ └── index.js │ ├── GroupBanner │ │ └── index.js │ ├── GroupButton │ │ ├── index.js │ │ ├── GroupButton.scss │ │ ├── __snapshots__ │ │ │ └── GroupButton.test.js.snap │ │ └── GroupButton.js │ ├── GroupsList │ │ ├── index.js │ │ └── GroupsList.scss │ ├── HyloEditor │ │ └── index.js │ ├── IconSelector │ │ └── index.js │ ├── LinkPreview │ │ └── index.js │ ├── Membership │ │ └── index.js │ ├── MultiSelect │ │ └── index.js │ ├── PostSelector │ │ └── index.js │ ├── PublicToggle │ │ └── index.js │ ├── RoundImage │ │ └── index.js │ ├── ScrollListener │ │ └── index.js │ ├── SliderInput │ │ └── index.js │ ├── ErrorBoundary │ │ └── index.js │ ├── GroupsSelector │ │ ├── index.js │ │ └── sampleGroup.js │ ├── ImageCarousel │ │ └── index.js │ ├── RemovableListItem │ │ ├── index.js │ │ └── RemovableListItem.scss │ ├── SettingsControl │ │ ├── index.js │ │ └── SettingsControl.test.js │ ├── SimpleTabBar │ │ ├── index.js │ │ ├── SimpleTabBar.js │ │ └── SimpleTabBar.scss │ ├── VisibilityToggle │ │ └── index.js │ ├── GroupNetworkMap │ │ └── index.js │ ├── HyloCookieConsent │ │ └── index.js │ ├── ModerationListItem │ │ └── index.js │ ├── PeopleTyping │ │ ├── PeopleTyping.scss │ │ ├── index.js │ │ ├── PeopleTyping.test.js │ │ └── PeopleTyping.connector.js │ ├── PostEditor │ │ ├── LinkPreview │ │ │ └── index.js │ │ ├── AnonymousVoteToggle │ │ │ └── index.js │ │ ├── StrictProposalToggle │ │ │ └── index.js │ │ └── index.js │ ├── PostPeopleDialog │ │ └── index.js │ ├── RoundImageRow │ │ ├── index.js │ │ └── RoundImageRow.test.js │ ├── TopicFeedHeader │ │ └── index.js │ ├── CardFileAttachments │ │ └── index.js │ ├── StreamViewControls │ │ └── index.js │ ├── CardImageAttachments │ │ └── index.js │ ├── GroupAboutVideoEmbed │ │ ├── index.js │ │ └── GroupAboutVideoEmbed.scss │ ├── KeyControlledList │ │ ├── index.js │ │ └── KeyControlledItemList.scss │ ├── Icon │ │ ├── index.js │ │ └── Icon.scss │ ├── GeocoderAutocomplete │ │ └── index.js │ ├── NoPosts │ │ ├── NoPosts.scss │ │ └── index.js │ ├── Member │ │ ├── index.js │ │ ├── __snapshots__ │ │ │ └── Member.connector.test.js.snap │ │ └── Member.connector.test.js │ ├── CreateGroup │ │ ├── index.js │ │ ├── __snapshots__ │ │ │ ├── CreateGroup.test.js.snap │ │ │ └── CreateGroup.connector.test.js.snap │ │ └── CreateGroup.test.js │ ├── CommentCard │ │ ├── index.js │ │ └── CommentCard.connector.js │ ├── CreateTopic │ │ ├── index.js │ │ └── CreateTopic.connector.js │ ├── LocationInput │ │ ├── index.js │ │ └── LocationInput.connector.js │ ├── MemberSelector │ │ └── index.js │ ├── SkillsSection │ │ └── index.js │ ├── SocketListener │ │ └── index.js │ ├── TopicSelector │ │ └── index.js │ ├── EventInviteDialog │ │ ├── index.js │ │ └── EventInviteDialog.store.test.js │ ├── AttachmentManager │ │ └── index.js │ ├── PostGridItem │ │ └── index.js │ ├── SocketSubscriber │ │ └── index.js │ ├── PostBigGridItem │ │ └── index.js │ ├── PostListRow │ │ ├── index.js │ │ └── PostListRow.connector.js │ ├── SkillsToLearnSection │ │ ├── index.js │ │ └── SkillsToLearnSection.js │ ├── UploadAttachmentButton │ │ ├── index.js │ │ ├── UploadAttachmentButton.connector.js │ │ └── UploadAttachmentButton.scss │ ├── FlagContent │ │ ├── FlagContent.connector.js │ │ ├── FlagContent.store.test.js │ │ └── index.js │ ├── TopicSupportComingSoon │ │ ├── TopicSupportComingSoon.test.js │ │ └── TopicSupportComingSoon.scss │ ├── ModalDialog │ │ └── index.js │ ├── FlagGroupContent │ │ └── index.js │ ├── SendAnnouncementModal │ │ └── index.js │ └── NotFound │ │ └── NotFound.connector.js ├── store │ ├── selectors │ │ ├── getReturnToPath.js │ │ ├── getPreviousLocation.js │ │ ├── getAnnouncementSelected.js │ │ ├── getRouteParam.js │ │ ├── getBlockedUsers.js │ │ ├── getMe.js │ │ ├── getCommonRoles.js │ │ ├── getMySkills.js │ │ ├── getPlatformAgreements.js │ │ ├── getPostById.js │ │ ├── getPerson.js │ │ ├── getMyJoinRequests.js │ │ ├── getGroupForCurrentRoute.js │ │ ├── getMyMemberships.js │ │ ├── getQuerystringParam.js │ │ ├── isGroupRoute.js │ │ ├── getGroupForDetails.js │ │ ├── getLastViewedGroup.js │ │ ├── getMyGroups.js │ │ ├── getPost.js │ │ ├── getChildComments.js │ │ ├── getMyGroupMembership.js │ │ └── getTopicForCurrentRoute.js │ ├── actions │ │ ├── resetStore.js │ │ ├── fetchTopic.test.js │ │ ├── logout.js │ │ ├── fetchGroupTopic.test.js │ │ ├── setReturnToPath.js │ │ ├── deleteMe.js │ │ ├── deactivateMe.js │ │ ├── resetNewPostCount.test.js │ │ ├── trackAnalyticsEvent.js │ │ ├── fetchPerson.js │ │ ├── fetchNotificationSettings.js │ │ ├── joinProject.js │ │ ├── leaveProject.js │ │ ├── checkIsPostPublic.js │ │ ├── deleteComment.js │ │ ├── deletePost.js │ │ ├── checkIsPublicGroup.js │ │ ├── sendPasswordReset.js │ │ ├── fetchPosts.test.js │ │ ├── fetchForCurrentUser.js │ │ ├── fetchPeople.test.js │ │ ├── fetchPlatformAgreements.js │ │ ├── removePost.js │ │ ├── blockUser.js │ │ ├── fetchTopic.js │ │ ├── unBlockUser.js │ │ ├── fetchMySkills.js │ │ └── fetchPerson.test.js │ ├── presenters │ │ ├── presentJoinRequest.js │ │ ├── presentTopic.js │ │ ├── presentGroupInvite.js │ │ ├── presentComment.js │ │ ├── presentCollection.js │ │ └── presentGroupRelationshipInvite.js │ ├── reducers │ │ ├── mixpanel.js │ │ ├── ormReducer │ │ │ ├── clearCacheFor.js │ │ │ └── clearCacheFor.test.js │ │ ├── util.js │ │ ├── locationHistory.js │ │ └── pending.js │ ├── models │ │ ├── Skill.js │ │ ├── LinkPreview.js │ │ ├── Widget.js │ │ ├── PostMembership.js │ │ ├── Agreement.js │ │ ├── PlatformAgreement.js │ │ ├── Message.js │ │ ├── PersonConnection.js │ │ ├── GroupTopic.js │ │ ├── ModerationAction.js │ │ ├── Topic.js │ │ ├── Activity.js │ │ ├── Comment.js │ │ ├── Invitation.js │ │ ├── Attachment.js │ │ └── SearchResult.js │ └── middleware │ │ ├── pendingMiddleware.js │ │ └── userBlockingMiddleware.js ├── util │ ├── filterDeletedUsers.js │ ├── debounced.js │ ├── url.js │ ├── mobile.test.js │ ├── generateTempId.js │ ├── testing │ │ └── extractModelsForTest.js │ ├── filterDeletedUsers.test.js │ ├── webView.js │ ├── asyncDebounce.js │ └── geo.js ├── config │ └── featureFlags.js ├── hooks │ └── useCurrentUser │ │ └── index.js ├── graphql │ ├── queries │ │ ├── postQuery.js │ │ ├── SubCommentsQuery.graphql │ │ ├── MessageThreadMessagesQuery.graphql │ │ ├── PeopleQuery.graphql │ │ └── MessageThreadQuery.graphql │ └── fragments │ │ ├── GroupTopicsFragment.graphql │ │ ├── groupsQueryFragment.js │ │ ├── CommentFieldsFragment.graphql │ │ └── groupTopicsQueryFragment.js ├── router │ └── RedirectRoute.js ├── client │ └── util.js ├── css │ ├── global │ │ └── index.scss │ └── bootstrap.scss └── server │ └── newrelic.js ├── .dockerignore ├── .github └── FUNDING.yml ├── Procfile ├── config ├── jest │ ├── __mocks__ │ │ ├── styleMock.js │ │ └── fileMock.js │ └── transformer.js └── postcss.config.js ├── scripts ├── templates │ ├── Component.scss │ ├── index.js │ ├── index.connected.js │ ├── Component.test.js │ ├── Component.js │ ├── Component.connector.js │ ├── Component.class.js │ └── Component.connectorWithStore.js ├── serveUniversal.js ├── serveStatic.js ├── generate.js └── build-es5.sh ├── public ├── gift.png ├── hylo.png ├── favicon.ico ├── favicon.png ├── apple-icon.png ├── axolotl-phone.png ├── default-event.png ├── favicon-16x16.png ├── favicon-32x32.png ├── favicon-96x96.png ├── happy-axolotl.png ├── hylo-merkaba.png ├── jolly-axolotl.png ├── mapIconAtlas.png ├── ms-icon-70x70.png ├── network-map-bg.png ├── public-context.png ├── signup-globe.png ├── signup-group.png ├── signup-stream.png ├── social-share.png ├── white-merkaba.png ├── apple-icon-57x57.png ├── apple-icon-60x60.png ├── apple-icon-72x72.png ├── apple-icon-76x76.png ├── confused-axolotl.png ├── grooving-axolotl.png ├── ms-icon-144x144.png ├── ms-icon-150x150.png ├── ms-icon-310x310.png ├── all-groups-banner.png ├── android-icon-36x36.png ├── android-icon-48x48.png ├── android-icon-72x72.png ├── android-icon-96x96.png ├── apple-icon-114x114.png ├── apple-icon-120x120.png ├── apple-icon-144x144.png ├── apple-icon-152x152.png ├── apple-icon-180x180.png ├── assets │ ├── hey-axolotl.png │ ├── axolotl-corner.png │ ├── default-avatar.png │ ├── white-merkaba.png │ ├── all-groups-avatar.png │ ├── create-post-pin.png │ ├── puzzled-axolotl.jpg │ ├── thinking-axolotl.png │ ├── default_group_avatar.png │ └── fonts │ │ ├── icons │ │ ├── hylo-evo-icons.eot │ │ ├── hylo-evo-icons.ttf │ │ └── hylo-evo-icons.woff │ │ └── Circular-Font-Family │ │ ├── lineto-circular-bold.ttf │ │ ├── lineto-circular-book.ttf │ │ ├── lineto-circular-black.ttf │ │ ├── lineto-circular-medium.ttf │ │ ├── lineto-circular-blackItalic.ttf │ │ ├── lineto-circular-boldItalic.ttf │ │ ├── lineto-circular-bookItalic.ttf │ │ └── lineto-circular-mediumItalic.ttf ├── axolotl-tourguide.png ├── location-icon-atlas.png ├── android-icon-144x144.png ├── android-icon-192x192.png ├── default-announcement.png ├── apple-icon-precomposed.png ├── william-white-34988-community.jpg ├── browserconfig.xml └── apple-app-site-association ├── .husky ├── pre-commit └── pre-push ├── NOTICE ├── .env.example ├── graphql.config.json ├── .codeclimate.yml ├── apollo.config.js ├── tsconfig.json ├── Dockerfile └── .gitignore /.nvmrc: -------------------------------------------------------------------------------- 1 | 16.13.2 2 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | public 3 | -------------------------------------------------------------------------------- /src/routes/GroupExplorer/GroupExplorer.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git 2 | node_modules 3 | build -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: hylo 2 | -------------------------------------------------------------------------------- /src/components/Widget/MapWidget/MapWidget.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node es5/scripts/serveUniversal 2 | -------------------------------------------------------------------------------- /config/jest/__mocks__/styleMock.js: -------------------------------------------------------------------------------- 1 | module.exports = {} 2 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/Sidebar/component.scss: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /scripts/templates/Component.scss: -------------------------------------------------------------------------------- 1 | .exampleName { /* !empty */ } 2 | -------------------------------------------------------------------------------- /config/jest/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub' 2 | -------------------------------------------------------------------------------- /public/gift.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/gift.png -------------------------------------------------------------------------------- /public/hylo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/hylo.png -------------------------------------------------------------------------------- /src/components/Map/index.js: -------------------------------------------------------------------------------- 1 | import Map from './Map' 2 | 3 | export default Map 4 | -------------------------------------------------------------------------------- /src/components/Widget/PrivacyWidget/Privacy.scss: -------------------------------------------------------------------------------- 1 | .privacy-container { 2 | 3 | } -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn lint 5 | -------------------------------------------------------------------------------- /scripts/serveUniversal.js: -------------------------------------------------------------------------------- 1 | import startServer from '../src/server' 2 | startServer() 3 | -------------------------------------------------------------------------------- /src/components/Widget/StewardsWidget/StewardsWidget.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/TopNavDropdown/TopNavDropdown.store.js: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/favicon.png -------------------------------------------------------------------------------- /public/apple-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon.png -------------------------------------------------------------------------------- /src/components/Button/index.js: -------------------------------------------------------------------------------- 1 | import component from './Button' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/Pill/index.js: -------------------------------------------------------------------------------- 1 | import component from './Pill' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Select/index.js: -------------------------------------------------------------------------------- 1 | import Select from './Select' 2 | 3 | export default Select 4 | -------------------------------------------------------------------------------- /src/components/Switch/index.js: -------------------------------------------------------------------------------- 1 | import component from './Switch' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/Widget/index.js: -------------------------------------------------------------------------------- 1 | import Widget from './Widget' 2 | 3 | export default Widget 4 | -------------------------------------------------------------------------------- /src/routes/OAuth/Login/index.js: -------------------------------------------------------------------------------- 1 | import component from './Login' 2 | export default component 3 | -------------------------------------------------------------------------------- /public/axolotl-phone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/axolotl-phone.png -------------------------------------------------------------------------------- /public/default-event.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/default-event.png -------------------------------------------------------------------------------- /public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/favicon-16x16.png -------------------------------------------------------------------------------- /public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/favicon-32x32.png -------------------------------------------------------------------------------- /public/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/favicon-96x96.png -------------------------------------------------------------------------------- /public/happy-axolotl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/happy-axolotl.png -------------------------------------------------------------------------------- /public/hylo-merkaba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/hylo-merkaba.png -------------------------------------------------------------------------------- /public/jolly-axolotl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/jolly-axolotl.png -------------------------------------------------------------------------------- /public/mapIconAtlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/mapIconAtlas.png -------------------------------------------------------------------------------- /public/ms-icon-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/ms-icon-70x70.png -------------------------------------------------------------------------------- /public/network-map-bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/network-map-bg.png -------------------------------------------------------------------------------- /public/public-context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/public-context.png -------------------------------------------------------------------------------- /public/signup-globe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/signup-globe.png -------------------------------------------------------------------------------- /public/signup-group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/signup-group.png -------------------------------------------------------------------------------- /public/signup-stream.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/signup-stream.png -------------------------------------------------------------------------------- /public/social-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/social-share.png -------------------------------------------------------------------------------- /public/white-merkaba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/white-merkaba.png -------------------------------------------------------------------------------- /scripts/templates/index.js: -------------------------------------------------------------------------------- 1 | import component from './Component' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Avatar/index.js: -------------------------------------------------------------------------------- 1 | import component from './Avatar' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Badge/index.js: -------------------------------------------------------------------------------- 1 | import component from './component' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/CheckBox/index.js: -------------------------------------------------------------------------------- 1 | import CheckBox from './CheckBox' 2 | 3 | export default CheckBox 4 | -------------------------------------------------------------------------------- /src/components/EmojiPill/index.js: -------------------------------------------------------------------------------- 1 | import component from './EmojiPill' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/EmojiRow/index.js: -------------------------------------------------------------------------------- 1 | import component from './EmojiRow' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/Loading/index.js: -------------------------------------------------------------------------------- 1 | import Loading from './Loading' 2 | 3 | export default Loading 4 | -------------------------------------------------------------------------------- /src/components/Pillbox/index.js: -------------------------------------------------------------------------------- 1 | import Pillbox from './Pillbox' 2 | 3 | export default Pillbox 4 | -------------------------------------------------------------------------------- /src/components/PostLabel/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostLabel' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/Tooltip/index.js: -------------------------------------------------------------------------------- 1 | import Tooltip from './Tooltip' 2 | 3 | export default Tooltip 4 | -------------------------------------------------------------------------------- /src/routes/JoinGroup/index.js: -------------------------------------------------------------------------------- 1 | import component from './JoinGroup' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /.husky/pre-push: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | yarn test -- --coverage --runInBand -------------------------------------------------------------------------------- /public/apple-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-57x57.png -------------------------------------------------------------------------------- /public/apple-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-60x60.png -------------------------------------------------------------------------------- /public/apple-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-72x72.png -------------------------------------------------------------------------------- /public/apple-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-76x76.png -------------------------------------------------------------------------------- /public/confused-axolotl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/confused-axolotl.png -------------------------------------------------------------------------------- /public/grooving-axolotl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/grooving-axolotl.png -------------------------------------------------------------------------------- /public/ms-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/ms-icon-144x144.png -------------------------------------------------------------------------------- /public/ms-icon-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/ms-icon-150x150.png -------------------------------------------------------------------------------- /public/ms-icon-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/ms-icon-310x310.png -------------------------------------------------------------------------------- /src/components/BadgedIcon/index.js: -------------------------------------------------------------------------------- 1 | import component from './component' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Dropdown/index.js: -------------------------------------------------------------------------------- 1 | import component from './Dropdown' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/EmojiPicker/index.js: -------------------------------------------------------------------------------- 1 | import component from './EmojiPicker' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/FancyLink/index.js: -------------------------------------------------------------------------------- 1 | import component from './FancyLink' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/GroupCard/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupCard' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Highlight/index.js: -------------------------------------------------------------------------------- 1 | import Highlight from './Highlight' 2 | 3 | export default Highlight 4 | -------------------------------------------------------------------------------- /src/components/HyloHTML/index.js: -------------------------------------------------------------------------------- 1 | import component from './HyloHTML' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/ModalFooter/index.js: -------------------------------------------------------------------------------- 1 | import component from './ModalFooter' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/ModalSidebar/index.js: -------------------------------------------------------------------------------- 1 | import component from './ModalSidebar' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/PostCard/ChatCard/index.js: -------------------------------------------------------------------------------- 1 | import ChatCard from './ChatCard' 2 | export default ChatCard 3 | -------------------------------------------------------------------------------- /src/components/PostCard/PostBody/index.js: -------------------------------------------------------------------------------- 1 | import PostBody from './PostBody' 2 | export default PostBody 3 | -------------------------------------------------------------------------------- /src/components/QuorumBar/index.js: -------------------------------------------------------------------------------- 1 | import component from './QuorumBar' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/SkillLabel/index.js: -------------------------------------------------------------------------------- 1 | import component from './component' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/SwitchStyled/index.js: -------------------------------------------------------------------------------- 1 | import component from './SwitchStyled' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/TagInput/index.js: -------------------------------------------------------------------------------- 1 | import component from './TagInput' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/TextInput/index.js: -------------------------------------------------------------------------------- 1 | import component from './TextInput' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Messages/Header/index.js: -------------------------------------------------------------------------------- 1 | import component from './Header' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Messages/Message/index.js: -------------------------------------------------------------------------------- 1 | import Message from './Message' 2 | 3 | export default Message 4 | -------------------------------------------------------------------------------- /src/routes/RootRouter/index.js: -------------------------------------------------------------------------------- 1 | import component from './RootRouter' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /public/all-groups-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/all-groups-banner.png -------------------------------------------------------------------------------- /public/android-icon-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/android-icon-36x36.png -------------------------------------------------------------------------------- /public/android-icon-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/android-icon-48x48.png -------------------------------------------------------------------------------- /public/android-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/android-icon-72x72.png -------------------------------------------------------------------------------- /public/android-icon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/android-icon-96x96.png -------------------------------------------------------------------------------- /public/apple-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-114x114.png -------------------------------------------------------------------------------- /public/apple-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-120x120.png -------------------------------------------------------------------------------- /public/apple-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-144x144.png -------------------------------------------------------------------------------- /public/apple-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-152x152.png -------------------------------------------------------------------------------- /public/apple-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-180x180.png -------------------------------------------------------------------------------- /public/assets/hey-axolotl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/hey-axolotl.png -------------------------------------------------------------------------------- /public/axolotl-tourguide.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/axolotl-tourguide.png -------------------------------------------------------------------------------- /public/location-icon-atlas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/location-icon-atlas.png -------------------------------------------------------------------------------- /src/components/Affiliation/index.js: -------------------------------------------------------------------------------- 1 | import component from './Affiliation' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/BadgeEmoji/index.js: -------------------------------------------------------------------------------- 1 | import component from './BadgeEmoji' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/ClickCatcher/index.js: -------------------------------------------------------------------------------- 1 | import component from './ClickCatcher' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/CreateModal/index.js: -------------------------------------------------------------------------------- 1 | import CreateModal from './CreateModal' 2 | export default CreateModal 3 | -------------------------------------------------------------------------------- /src/components/DropdownButton/index.js: -------------------------------------------------------------------------------- 1 | import component from './DropdownButton' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/FarmGroupDetailBody/FarmGroupDetailBody.scss: -------------------------------------------------------------------------------- 1 | .farm-group-detail-body { 2 | padding: 0; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/GoogleButton/index.js: -------------------------------------------------------------------------------- 1 | import component from './GoogleButton' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/GroupBanner/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupBanner' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/GroupButton/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupButton' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/GroupsList/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupsList' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/HyloEditor/index.js: -------------------------------------------------------------------------------- 1 | import component from './HyloEditor' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/IconSelector/index.js: -------------------------------------------------------------------------------- 1 | import component from './IconSelector' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/LinkPreview/index.js: -------------------------------------------------------------------------------- 1 | import component from './LinkPreview' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Membership/index.js: -------------------------------------------------------------------------------- 1 | import component from './Membership' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/MultiSelect/index.js: -------------------------------------------------------------------------------- 1 | import component from './MultiSelect' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/Feature/index.js: -------------------------------------------------------------------------------- 1 | import component from './Feature' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostSelector/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostSelector' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PublicToggle/index.js: -------------------------------------------------------------------------------- 1 | import component from './PublicToggle' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/RoundImage/index.js: -------------------------------------------------------------------------------- 1 | import component from './RoundImage' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/ScrollListener/index.js: -------------------------------------------------------------------------------- 1 | import component from './ScrollListener' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/SliderInput/index.js: -------------------------------------------------------------------------------- 1 | import component from './SliderInput' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/ChatRoom/ChatPost/index.js: -------------------------------------------------------------------------------- 1 | import component from './ChatPost' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/GroupExplorer/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupExplorer' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /public/android-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/android-icon-144x144.png -------------------------------------------------------------------------------- /public/android-icon-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/android-icon-192x192.png -------------------------------------------------------------------------------- /public/assets/axolotl-corner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/axolotl-corner.png -------------------------------------------------------------------------------- /public/assets/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/default-avatar.png -------------------------------------------------------------------------------- /public/assets/white-merkaba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/white-merkaba.png -------------------------------------------------------------------------------- /public/default-announcement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/default-announcement.png -------------------------------------------------------------------------------- /src/components/ErrorBoundary/index.js: -------------------------------------------------------------------------------- 1 | import ErrorBoundary from './ErrorBoundary' 2 | export default ErrorBoundary 3 | -------------------------------------------------------------------------------- /src/components/GroupsSelector/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupsSelector' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/ImageCarousel/index.js: -------------------------------------------------------------------------------- 1 | import component from './ImageCarousel' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/EventBody/index.js: -------------------------------------------------------------------------------- 1 | import component from './EventBody' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/EventDate/index.js: -------------------------------------------------------------------------------- 1 | import component from './EventDate' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/EventRSVP/index.js: -------------------------------------------------------------------------------- 1 | import component from './EventRSVP' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/PeopleInfo/index.js: -------------------------------------------------------------------------------- 1 | import component from './PeopleInfo' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/PostFooter/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostFooter' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/PostTitle/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostTitle' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/RemovableListItem/index.js: -------------------------------------------------------------------------------- 1 | import component from './RemovableListItem' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/SettingsControl/index.js: -------------------------------------------------------------------------------- 1 | import component from './SettingsControl' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/SimpleTabBar/index.js: -------------------------------------------------------------------------------- 1 | import SimpleTabBar from './SimpleTabBar' 2 | export default SimpleTabBar 3 | -------------------------------------------------------------------------------- /src/components/VisibilityToggle/index.js: -------------------------------------------------------------------------------- 1 | import component from './VisibilityToggle' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/Widget/JoinWidget/index.js: -------------------------------------------------------------------------------- 1 | import JoinWidget from './JoinWidget' 2 | 3 | export default JoinWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/MapWidget/index.js: -------------------------------------------------------------------------------- 1 | import MapWidget from './MapWidget' 2 | 3 | export default MapWidget 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/index.js: -------------------------------------------------------------------------------- 1 | import component from './AuthLayoutRouter' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/MapExplorer/MapDrawer/index.js: -------------------------------------------------------------------------------- 1 | import MapDrawer from './MapDrawer' 2 | 3 | export default MapDrawer 4 | -------------------------------------------------------------------------------- /src/routes/Messages/MessageForm/index.js: -------------------------------------------------------------------------------- 1 | import component from './MessageForm' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Login/index.js: -------------------------------------------------------------------------------- 1 | import component from './Login' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Signup/index.js: -------------------------------------------------------------------------------- 1 | import component from './Signup' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/store/selectors/getReturnToPath.js: -------------------------------------------------------------------------------- 1 | import { get } from 'lodash/fp' 2 | 3 | export default get('returnToPath') 4 | -------------------------------------------------------------------------------- /public/apple-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/apple-icon-precomposed.png -------------------------------------------------------------------------------- /public/assets/all-groups-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/all-groups-avatar.png -------------------------------------------------------------------------------- /public/assets/create-post-pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/create-post-pin.png -------------------------------------------------------------------------------- /public/assets/puzzled-axolotl.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/puzzled-axolotl.jpg -------------------------------------------------------------------------------- /public/assets/thinking-axolotl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/thinking-axolotl.png -------------------------------------------------------------------------------- /src/components/GroupCard/GroupHeader/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupHeader' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/GroupNetworkMap/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupNetworkMap' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/HyloCookieConsent/index.js: -------------------------------------------------------------------------------- 1 | import component from './HyloCookieConsent' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/ModerationListItem/index.js: -------------------------------------------------------------------------------- 1 | import component from './ModerationListItem' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/components/PeopleTyping/PeopleTyping.scss: -------------------------------------------------------------------------------- 1 | .typing { 2 | composes: faint-lt-sm from 'css/typography.scss'; 3 | } 4 | -------------------------------------------------------------------------------- /src/components/PostCard/PostDetails/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostDetails' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostEditor/LinkPreview/index.js: -------------------------------------------------------------------------------- 1 | import LinkPreview from './LinkPreview' 2 | export default LinkPreview 3 | -------------------------------------------------------------------------------- /src/components/PostPeopleDialog/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostPeopleDialog' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/RoundImageRow/index.js: -------------------------------------------------------------------------------- 1 | import RoundImageRow from './RoundImageRow' 2 | 3 | export default RoundImageRow 4 | -------------------------------------------------------------------------------- /src/components/TopicFeedHeader/index.js: -------------------------------------------------------------------------------- 1 | import component from './TopicFeedHeader' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/GroupExplorer/GroupSearch/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupSearch' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/GroupWelcomeModal/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupWelcomeModal' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Messages/CloseMessages/index.js: -------------------------------------------------------------------------------- 1 | import component from './CloseMessages' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Messages/MessageSection/index.js: -------------------------------------------------------------------------------- 1 | import component from './MessageSection' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Messages/PeopleSelector/index.js: -------------------------------------------------------------------------------- 1 | import component from './PeopleSelector' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/index.js: -------------------------------------------------------------------------------- 1 | import component from './NonAuthLayoutRouter' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/PublicLayoutRouter/index.js: -------------------------------------------------------------------------------- 1 | import component from './PublicLayoutRouter' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/index.js: -------------------------------------------------------------------------------- 1 | import component from './WelcomeWizardRouter' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/CardFileAttachments/index.js: -------------------------------------------------------------------------------- 1 | import component from './CardFileAttachments' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/FarmGroupDetailBody/index.js: -------------------------------------------------------------------------------- 1 | import component from './FarmGroupDetailBody' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/PostCard/PostCompletion/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostCompletion' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/StreamViewControls/index.js: -------------------------------------------------------------------------------- 1 | import Component from './StreamViewControls' 2 | 3 | export default Component 4 | -------------------------------------------------------------------------------- /src/components/Widget/AtAGlanceWidget/index.js: -------------------------------------------------------------------------------- 1 | import component from './AtAGlanceWidget' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Widget/EventsWidget/index.js: -------------------------------------------------------------------------------- 1 | import EventsWidget from './EventsWidget' 2 | 3 | export default EventsWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/FarmOpenToPublic/index.js: -------------------------------------------------------------------------------- 1 | import component from './FarmOpenToPublic' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Widget/GroupsWidget/index.js: -------------------------------------------------------------------------------- 1 | import GroupsWidget from './GroupsWidget' 2 | 3 | export default GroupsWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/RichTextWidget/index.js: -------------------------------------------------------------------------------- 1 | import component from './RichTextWidget' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Widget/TopicsWidget/index.js: -------------------------------------------------------------------------------- 1 | import TopicsWidget from './TopicsWidget' 2 | 3 | export default TopicsWidget 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/Drawer/index.js: -------------------------------------------------------------------------------- 1 | import component from './Drawer' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/Sidebar/index.js: -------------------------------------------------------------------------------- 1 | import component from './component' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/routes/GroupExplorer/ExplorerBanner/index.js: -------------------------------------------------------------------------------- 1 | import component from './ExplorerBanner' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/ExportDataTab/index.js: -------------------------------------------------------------------------------- 1 | import ExportDataTab from './ExportDataTab' 2 | export default ExportDataTab 3 | -------------------------------------------------------------------------------- /src/routes/UserSettings/BlockedUsersTab/index.js: -------------------------------------------------------------------------------- 1 | import component from './BlockedUsersTab' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Hylo 2 | Copyright 2020 Holo Ltd 3 | 4 | This product includes software developed by Terran Collective (https://terran.io) -------------------------------------------------------------------------------- /public/assets/default_group_avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/default_group_avatar.png -------------------------------------------------------------------------------- /public/william-white-34988-community.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/william-white-34988-community.jpg -------------------------------------------------------------------------------- /src/components/CardImageAttachments/index.js: -------------------------------------------------------------------------------- 1 | import component from './CardImageAttachments' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/GroupAboutVideoEmbed/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupAboutVideoEmbed' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/KeyControlledList/index.js: -------------------------------------------------------------------------------- 1 | export { 2 | default, 3 | KeyControlledItemList 4 | } from './KeyControlledList' 5 | -------------------------------------------------------------------------------- /src/components/PostCard/PostBodyProposal/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostBodyProposal' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Widget/FarmDetailsWidget/index.js: -------------------------------------------------------------------------------- 1 | import component from './FarmDetailsWidget' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Widget/FarmMapWidget/index.js: -------------------------------------------------------------------------------- 1 | import FarmMapWidget from './FarmMapWidget' 2 | 3 | export default FarmMapWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/MembersWidget/index.js: -------------------------------------------------------------------------------- 1 | import MembersWidget from './MembersWidget' 2 | 3 | export default MembersWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/PrivacyWidget/index.js: -------------------------------------------------------------------------------- 1 | import PrivacyWidget from './PrivacyWidget' 2 | 3 | export default PrivacyWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/WelcomeWidget/index.js: -------------------------------------------------------------------------------- 1 | import WelcomeWidget from './WelcomeWidget' 2 | 3 | export default WelcomeWidget 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/SiteTour/index.js: -------------------------------------------------------------------------------- 1 | import component from './SiteTour' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/NoItems/index.js: -------------------------------------------------------------------------------- 1 | import component from './NoItems' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/routes/GroupExplorer/GroupViewFilter/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupViewFilter' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/AgreementsTab/index.js: -------------------------------------------------------------------------------- 1 | import AgreementsTab from './AgreementsTab' 2 | 3 | export default AgreementsTab 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/ResponsibilitiesTab/index.js: -------------------------------------------------------------------------------- 1 | import component from './ResponsibilitiesTab' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/routes/MapExplorer/SavedSearches/index.js: -------------------------------------------------------------------------------- 1 | import SavedSearches from './SavedSearches' 2 | 3 | export default SavedSearches 4 | -------------------------------------------------------------------------------- /src/routes/Messages/PeopleSelector/PeopleList/index.js: -------------------------------------------------------------------------------- 1 | import component from './PeopleList' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /scripts/serveStatic.js: -------------------------------------------------------------------------------- 1 | const server = require('pushstate-server') 2 | server.start({ port: process.env.PORT, directory: './build' }) 3 | -------------------------------------------------------------------------------- /src/components/PostEditor/AnonymousVoteToggle/index.js: -------------------------------------------------------------------------------- 1 | import component from './AnonymousVoteToggle' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/components/Widget/ProjectsWidget/index.js: -------------------------------------------------------------------------------- 1 | import ProjectsWidget from './ProjectsWidget' 2 | 3 | export default ProjectsWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/StewardsWidget/index.js: -------------------------------------------------------------------------------- 1 | import StewardsWidget from './StewardsWidget' 2 | 3 | export default StewardsWidget 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/Navigation/NavLink/index.js: -------------------------------------------------------------------------------- 1 | import component from './NavLink' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/CustomViewsTab/index.js: -------------------------------------------------------------------------------- 1 | import CustomViewsTab from './CustomViewsTab' 2 | 3 | export default CustomViewsTab 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/PrivacySettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import component from './PrivacySettingsTab' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Messages/PeopleSelector/PeopleListItem/index.js: -------------------------------------------------------------------------------- 1 | import component from './PeopleListItem' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/ManageNotifications/index.js: -------------------------------------------------------------------------------- 1 | import component from './ManageNotifications' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Signup/VerifyEmail/index.js: -------------------------------------------------------------------------------- 1 | import component from './VerifyEmail' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/PostDetail/ProjectContributions/index.js: -------------------------------------------------------------------------------- 1 | import component from './ProjectContributions' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/UserSettings/EditProfileTab/index.js: -------------------------------------------------------------------------------- 1 | import EditProfileTab from './EditProfileTab' 2 | 3 | export default EditProfileTab 4 | -------------------------------------------------------------------------------- /public/assets/fonts/icons/hylo-evo-icons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/icons/hylo-evo-icons.eot -------------------------------------------------------------------------------- /public/assets/fonts/icons/hylo-evo-icons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/icons/hylo-evo-icons.ttf -------------------------------------------------------------------------------- /public/assets/fonts/icons/hylo-evo-icons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/icons/hylo-evo-icons.woff -------------------------------------------------------------------------------- /src/components/Icon/index.js: -------------------------------------------------------------------------------- 1 | import component from './Icon' 2 | 3 | export { IconWithRef } from './Icon' 4 | 5 | export default component 6 | -------------------------------------------------------------------------------- /src/components/PostEditor/StrictProposalToggle/index.js: -------------------------------------------------------------------------------- 1 | import component from './StrictProposalToggle' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/LoadingItems/index.js: -------------------------------------------------------------------------------- 1 | import component from './LoadingItems' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/TopNavDropdown/index.js: -------------------------------------------------------------------------------- 1 | import component from './TopNavDropdown' 2 | export default component 3 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/SettingsSection/index.js: -------------------------------------------------------------------------------- 1 | import SettingsSection from './SettingsSection' 2 | 3 | export default SettingsSection 4 | -------------------------------------------------------------------------------- /src/components/GeocoderAutocomplete/index.js: -------------------------------------------------------------------------------- 1 | import GeocoderAutocomplete from './GeocoderAutocomplete' 2 | export default GeocoderAutocomplete 3 | -------------------------------------------------------------------------------- /src/components/PostCard/EventRSVP/EventRSVP.scss: -------------------------------------------------------------------------------- 1 | .eventRSVP { 2 | display: flex; 3 | flex-direction: column; 4 | margin-left: auto; 5 | } 6 | -------------------------------------------------------------------------------- /src/components/Widget/GroupTopicsWidget/index.js: -------------------------------------------------------------------------------- 1 | import GroupTopicsWidget from './GroupTopicsWidget' 2 | 3 | export default GroupTopicsWidget 4 | -------------------------------------------------------------------------------- /src/components/Widget/RecentPostsWidget/index.js: -------------------------------------------------------------------------------- 1 | import RecentPostsWidget from './RecentPostsWidget' 2 | 3 | export default RecentPostsWidget 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/LocaleDropdown/index.js: -------------------------------------------------------------------------------- 1 | import component from './LocaleDropdown' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/DeleteSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import DeleteSettingsTab from './DeleteSettingsTab' 2 | export default DeleteSettingsTab 3 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/GroupSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import GroupSettingsTab from './GroupSettingsTab' 2 | 3 | export default GroupSettingsTab 4 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Signup/FinishRegistration/index.js: -------------------------------------------------------------------------------- 1 | import component from './FinishRegistration' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Search/index.js: -------------------------------------------------------------------------------- 1 | import Search from './Search' 2 | import connector from './Search.connector' 3 | export default connector(Search) 4 | -------------------------------------------------------------------------------- /src/routes/UserSettings/SavedSearchesTab/index.js: -------------------------------------------------------------------------------- 1 | import SavedSearchesTab from './SavedSearchesTab' 2 | 3 | export default SavedSearchesTab 4 | -------------------------------------------------------------------------------- /src/components/Widget/AnnouncementWidget/index.js: -------------------------------------------------------------------------------- 1 | import AnnouncementWidget from './AnnouncementWidget' 2 | 3 | export default AnnouncementWidget 4 | -------------------------------------------------------------------------------- /src/routes/Groups/index.js: -------------------------------------------------------------------------------- 1 | import Groups from './Groups' 2 | import connector from './Groups.connector' 3 | 4 | export default connector(Groups) 5 | -------------------------------------------------------------------------------- /src/routes/Members/index.js: -------------------------------------------------------------------------------- 1 | import Members from './Members' 2 | import connector from './Members.connector' 3 | export default connector(Members) 4 | -------------------------------------------------------------------------------- /src/routes/Messages/PeopleSelector/MatchingPeopleListItem/index.js: -------------------------------------------------------------------------------- 1 | import component from './MatchingPeopleListItem' 2 | 3 | export default component 4 | -------------------------------------------------------------------------------- /src/routes/Stream/index.js: -------------------------------------------------------------------------------- 1 | import Stream from './Stream' 2 | import connector from './Stream.connector' 3 | 4 | export default connector(Stream) 5 | -------------------------------------------------------------------------------- /src/routes/UserSettings/AccountSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import AccountSettingsTab from './AccountSettingsTab' 2 | 3 | export default AccountSettingsTab 4 | -------------------------------------------------------------------------------- /src/routes/UserSettings/PaymentSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import PaymentSettingsTab from './PaymentSettingsTab' 2 | 3 | export default PaymentSettingsTab 4 | -------------------------------------------------------------------------------- /config/jest/transformer.js: -------------------------------------------------------------------------------- 1 | module.exports = require('babel-jest').default.createTransformer( 2 | require(require('../paths').babelConfigFile)() 3 | ) 4 | -------------------------------------------------------------------------------- /src/components/NoPosts/NoPosts.scss: -------------------------------------------------------------------------------- 1 | .no-posts { 2 | text-align: center; 3 | margin-top: 50px; 4 | 5 | img { 6 | height: 97px; 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/routes/Events/index.js: -------------------------------------------------------------------------------- 1 | import component from './Events' 2 | import connector from './Events.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/util/filterDeletedUsers.js: -------------------------------------------------------------------------------- 1 | export default function filterDeletedUsers (user) { 2 | return user.name && !user.name.includes('Deleted User') 3 | } 4 | -------------------------------------------------------------------------------- /src/components/Member/index.js: -------------------------------------------------------------------------------- 1 | import component from './Member' 2 | import connector from './Member.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/AllTopics/index.js: -------------------------------------------------------------------------------- 1 | import AllTopics from './AllTopics' 2 | import connector from './AllTopics.connector' 3 | export default connector(AllTopics) 4 | -------------------------------------------------------------------------------- /src/routes/ChatRoom/index.js: -------------------------------------------------------------------------------- 1 | import component from './ChatRoom' 2 | import connector from './ChatRoom.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/GroupWelcomeModal/__snapshots__/GroupWelcomeModal.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`does something 1`] = `""`; 4 | -------------------------------------------------------------------------------- /src/routes/Messages/index.js: -------------------------------------------------------------------------------- 1 | import component from './Messages' 2 | import connector from './Messages.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/OAuth/Consent/index.js: -------------------------------------------------------------------------------- 1 | import component from './Consent' 2 | import connector from './Consent.connector' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /scripts/templates/index.connected.js: -------------------------------------------------------------------------------- 1 | import component from './Component' 2 | import connector from './Component.connector' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/ImportExportSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import ImportExportSettingsTab from './ImportExportSettingsTab' 2 | export default ImportExportSettingsTab 3 | -------------------------------------------------------------------------------- /src/routes/PostDetail/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostDetail' 2 | import connector from './PostDetail.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/CreateGroup/index.js: -------------------------------------------------------------------------------- 1 | import CreateGroup from './CreateGroup' 2 | import connector from './CreateGroup.connector' 3 | export default connector(CreateGroup) 4 | -------------------------------------------------------------------------------- /src/components/PostEditor/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostEditor' 2 | import connector from './PostEditor.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/Widget/OffersAndRequestsWidget/index.js: -------------------------------------------------------------------------------- 1 | import OffersAndRequestsWidget from './OffersAndRequestsWidget' 2 | 3 | export default OffersAndRequestsWidget 4 | -------------------------------------------------------------------------------- /src/routes/GroupDetail/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupDetail' 2 | import connector from './GroupDetail.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/GroupSidebar/index.js: -------------------------------------------------------------------------------- 1 | import component from './GroupSidebar' 2 | import connector from './GroupSidebar.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/LandingPage/index.js: -------------------------------------------------------------------------------- 1 | import component from './LandingPage' 2 | import connector from './LandingPage.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/MapExplorer/index.js: -------------------------------------------------------------------------------- 1 | import component from './MapExplorer' 2 | import connector from './MapExplorer.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/PostDetail/Comments/ShowMore.scss: -------------------------------------------------------------------------------- 1 | .showMore { 2 | padding: 0 25px; 3 | margin-bottom: 20px; 4 | composes: text-button from 'css/typography.scss'; 5 | } 6 | -------------------------------------------------------------------------------- /src/routes/UserSettings/NotificationSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import NotificationSettingsTab from './NotificationSettingsTab' 2 | 3 | export default NotificationSettingsTab 4 | -------------------------------------------------------------------------------- /config/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | 'postcss-flexbugs-fixes': {}, 4 | 'postcss-preset-env': { 5 | stage: 3 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/components/CommentCard/index.js: -------------------------------------------------------------------------------- 1 | import component from './CommentCard' 2 | import connector from './CommentCard.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/CreateTopic/index.js: -------------------------------------------------------------------------------- 1 | import CreateTopic from './CreateTopic' 2 | import connector from './CreateTopic.connector' 3 | 4 | export default connector(CreateTopic) 5 | -------------------------------------------------------------------------------- /src/components/PeopleTyping/index.js: -------------------------------------------------------------------------------- 1 | import PeopleTyping from './PeopleTyping' 2 | import connector from './PeopleTyping.connector' 3 | export default connector(PeopleTyping) 4 | -------------------------------------------------------------------------------- /src/components/PostCard/PostHeader/index.js: -------------------------------------------------------------------------------- 1 | import PostHeader from './PostHeader' 2 | import connector from './PostHeader.connector' 3 | export default connector(PostHeader) 4 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/index.js: -------------------------------------------------------------------------------- 1 | import component from './TopNav' 2 | import connector from './TopNav.connector' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /src/routes/Messages/ThreadList/index.js: -------------------------------------------------------------------------------- 1 | import ThreadList from './ThreadList' 2 | import { withRouter } from 'react-router-dom' 3 | 4 | export default withRouter(ThreadList) 5 | -------------------------------------------------------------------------------- /src/routes/PostDetail/Comments/Comment/index.js: -------------------------------------------------------------------------------- 1 | import Comment from './Comment' 2 | import connector from './Comment.connector' 3 | 4 | export default connector(Comment) 5 | -------------------------------------------------------------------------------- /src/routes/UserSettings/index.js: -------------------------------------------------------------------------------- 1 | import UserSettings from './UserSettings' 2 | import connector from './UserSettings.connector' 3 | export default connector(UserSettings) 4 | -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-bold.ttf -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-book.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-book.ttf -------------------------------------------------------------------------------- /src/components/LocationInput/index.js: -------------------------------------------------------------------------------- 1 | import component from './LocationInput' 2 | import connector from './LocationInput.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/MemberSelector/index.js: -------------------------------------------------------------------------------- 1 | import component from './MemberSelector' 2 | import connector from './MemberSelector.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/PostCard/PostGroups/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostGroups' 2 | import connector from './PostGroups.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/SkillsSection/index.js: -------------------------------------------------------------------------------- 1 | import SkillsSection from './SkillsSection' 2 | import connector from './SkillsSection.connector' 3 | export default connector(SkillsSection) 4 | -------------------------------------------------------------------------------- /src/components/SocketListener/index.js: -------------------------------------------------------------------------------- 1 | import component from './SocketListener' 2 | import connector from './SocketListener.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/TopicSelector/index.js: -------------------------------------------------------------------------------- 1 | import component from './TopicSelector' 2 | import connector from './TopicSelector.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/index.js: -------------------------------------------------------------------------------- 1 | import GroupSettings from './GroupSettings' 2 | import connector from './GroupSettings.connector' 3 | export default connector(GroupSettings) 4 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberPosts/index.js: -------------------------------------------------------------------------------- 1 | import MemberPosts from './MemberPosts' 2 | import connector from './MemberPosts.connector' 3 | export default connector(MemberPosts) 4 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/index.js: -------------------------------------------------------------------------------- 1 | import MemberProfile from './MemberProfile' 2 | import connector from './MemberProfile.connector' 3 | export default connector(MemberProfile) 4 | -------------------------------------------------------------------------------- /src/store/actions/resetStore.js: -------------------------------------------------------------------------------- 1 | import { RESET_STORE } from '../constants' 2 | 3 | export default function resetStore () { 4 | return { 5 | type: RESET_STORE 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/store/selectors/getPreviousLocation.js: -------------------------------------------------------------------------------- 1 | import { get } from 'lodash/fp' 2 | 3 | export default (state) => get('locationHistory.previousLocation', state) || { pathname: '/' } 4 | -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-black.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-black.ttf -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-medium.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-medium.ttf -------------------------------------------------------------------------------- /src/components/EventInviteDialog/index.js: -------------------------------------------------------------------------------- 1 | import connector from './EventInviteDialog.connector' 2 | import component from './EventInviteDialog' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /src/routes/FullPageModal/index.js: -------------------------------------------------------------------------------- 1 | import FullPageModal from './FullPageModal' 2 | import connector from './FullPageModal.connector' 3 | 4 | export default connector(FullPageModal) 5 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/AddLocation/index.js: -------------------------------------------------------------------------------- 1 | import component from './AddLocation' 2 | import connector from './AddLocation.connector' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/UploadPhoto/index.js: -------------------------------------------------------------------------------- 1 | import component from './UploadPhoto' 2 | import connector from './UploadPhoto.connector' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /src/components/AttachmentManager/index.js: -------------------------------------------------------------------------------- 1 | import component from './AttachmentManager' 2 | import connector from './AttachmentManager.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/PostGridItem/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostGridItem' 2 | import connector from '../PostListRow/PostListRow.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/SocketSubscriber/index.js: -------------------------------------------------------------------------------- 1 | import connector from './SocketSubscriber.connector' 2 | import component from './SocketSubscriber' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/PasswordReset/index.js: -------------------------------------------------------------------------------- 1 | import component from './PasswordReset' 2 | import connector from './PasswordReset.connector' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /src/routes/PostDetail/Comments/CommentForm/index.js: -------------------------------------------------------------------------------- 1 | import component from './CommentForm' 2 | import connector from './CommentForm.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/UserSettings/UserGroupsTab/index.js: -------------------------------------------------------------------------------- 1 | import UserGroupsTab from './UserGroupsTab' 2 | import connector from './UserGroupsTab.connector' 3 | export default connector(UserGroupsTab) 4 | -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-blackItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-blackItalic.ttf -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-boldItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-boldItalic.ttf -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-bookItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-bookItalic.ttf -------------------------------------------------------------------------------- /src/components/PostBigGridItem/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostBigGridItem' 2 | import connector from '../PostListRow/PostListRow.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/config/featureFlags.js: -------------------------------------------------------------------------------- 1 | export const PROJECT_CONTRIBUTIONS = 'PROJECT_CONTRIBUTIONS' 2 | 3 | const featureFlag = key => process.env['FEATURE_FLAG_' + key] 4 | 5 | export default featureFlag 6 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/Navigation/index.js: -------------------------------------------------------------------------------- 1 | import component from './Navigation' 2 | import connector from './Navigation.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberComments/index.js: -------------------------------------------------------------------------------- 1 | import MemberComments from './MemberComments' 2 | import connector from './MemberComments.connector' 3 | export default connector(MemberComments) 4 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/RecentActivity/index.js: -------------------------------------------------------------------------------- 1 | import RecentActivity from './RecentActivity' 2 | import connector from './RecentActivity.connector' 3 | export default connector(RecentActivity) 4 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/UploadPhoto/__snapshots__/UploadPhoto.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`UploadPhoto renders correctly 1`] = ``; 4 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/WelcomeExplore/index.js: -------------------------------------------------------------------------------- 1 | import component from './WelcomeExplore' 2 | import connector from './WelcomeExplore.connector' 3 | export default connector(component) 4 | -------------------------------------------------------------------------------- /public/assets/fonts/Circular-Font-Family/lineto-circular-mediumItalic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hylozoic/hylo-evo/HEAD/public/assets/fonts/Circular-Font-Family/lineto-circular-mediumItalic.ttf -------------------------------------------------------------------------------- /src/components/PostListRow/index.js: -------------------------------------------------------------------------------- 1 | import PostRow from './PostListRow' 2 | import connector from './PostListRow.connector' 3 | import './PostListRow.scss' 4 | 5 | export default connector(PostRow) 6 | -------------------------------------------------------------------------------- /src/store/selectors/getAnnouncementSelected.js: -------------------------------------------------------------------------------- 1 | const getAnnouncementSelected = (state, type) => { 2 | return state.PostEditor.postType === type 3 | } 4 | 5 | export default getAnnouncementSelected 6 | -------------------------------------------------------------------------------- /src/components/Widget/OpportunitiesToCollaborateWidget/index.js: -------------------------------------------------------------------------------- 1 | import OpportunitiesToCollaborateWidget from './OpportunitiesToCollaborateWidget' 2 | 3 | export default OpportunitiesToCollaborateWidget 4 | -------------------------------------------------------------------------------- /src/hooks/useCurrentUser/index.js: -------------------------------------------------------------------------------- 1 | import getMe from 'store/selectors/getMe' 2 | import { useSelector } from 'react-redux' 3 | 4 | export function useCurrentUser () { 5 | return useSelector(getMe) 6 | } 7 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/RelatedGroupsTab/index.js: -------------------------------------------------------------------------------- 1 | import RelatedGroupsTab from './RelatedGroupsTab' 2 | import connector from './RelatedGroupsTab.connector' 3 | export default connector(RelatedGroupsTab) 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/RolesSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import RolesSettingsTab from './RolesSettingsTab' 2 | import connector from './RolesSettingsTab.connector' 3 | export default connector(RolesSettingsTab) 4 | -------------------------------------------------------------------------------- /src/routes/UserSettings/ManageInvitesTab/index.js: -------------------------------------------------------------------------------- 1 | import ManageInvitesTab from './ManageInvitesTab' 2 | import connector from './ManageInvitesTab.connector' 3 | export default connector(ManageInvitesTab) 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/InviteSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import InviteSettingsTab from './InviteSettingsTab' 2 | import connector from './InviteSettingsTab.connector' 3 | export default connector(InviteSettingsTab) 4 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/TopicsSettingsTab/index.js: -------------------------------------------------------------------------------- 1 | import TopicsSettingsTab from './TopicsSettingsTab' 2 | import connector from './TopicsSettingsTab.connector' 3 | export default connector(TopicsSettingsTab) 4 | -------------------------------------------------------------------------------- /src/components/SkillsToLearnSection/index.js: -------------------------------------------------------------------------------- 1 | import SkillsToLearnSection from './SkillsToLearnSection' 2 | import connector from './SkillsToLearnSection.connector' 3 | export default connector(SkillsToLearnSection) 4 | -------------------------------------------------------------------------------- /src/graphql/queries/postQuery.js: -------------------------------------------------------------------------------- 1 | import postFieldsFragment from '../fragments/postFieldsFragment' 2 | 3 | export default 4 | `query ($id: ID) { 5 | post(id: $id) { 6 | ${postFieldsFragment(true)} 7 | } 8 | }` 9 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/MessagesDropdown/index.js: -------------------------------------------------------------------------------- 1 | import component from './MessagesDropdown' 2 | import connector from './MessagesDropdown.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/store/presenters/presentJoinRequest.js: -------------------------------------------------------------------------------- 1 | export default function presentJoinRequest (jr) { 2 | if (!jr) return null 3 | 4 | return { 5 | ...jr.ref, 6 | group: jr.group ? jr.group.ref : null 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/components/GroupButton/GroupButton.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | display: inline-block; 3 | padding: 6px 10px 4px 6px; 4 | 5 | a { 6 | color: #808C9B; 7 | text-decoration: none !important; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/routes/GroupExplorer/GroupViewFilter/GroupViewFilter.scss: -------------------------------------------------------------------------------- 1 | .filter-container { 2 | height: auto; 3 | width: 100%; 4 | display: flex; 5 | justify-content: center; 6 | gap: 8px; 7 | padding: 20px 0 0 0; 8 | } 9 | -------------------------------------------------------------------------------- /src/components/GroupAboutVideoEmbed/GroupAboutVideoEmbed.scss: -------------------------------------------------------------------------------- 1 | .videoContainer { 2 | position: relative; 3 | padding-top: 56.25% 4 | } 5 | 6 | .video { 7 | position: absolute; 8 | top: 0; 9 | left: 0; 10 | } 11 | -------------------------------------------------------------------------------- /src/components/PostCard/PostHeader/PostHeader.store.test.js: -------------------------------------------------------------------------------- 1 | import { pinPost } from './PostHeader.store' 2 | 3 | describe('pinPost', () => { 4 | it('matches last snapshot', () => expect(pinPost(1, 2)).toMatchSnapshot()) 5 | }) 6 | -------------------------------------------------------------------------------- /src/components/UploadAttachmentButton/index.js: -------------------------------------------------------------------------------- 1 | import UploadAttachmentButton from './UploadAttachmentButton' 2 | import connector from './UploadAttachmentButton.connector' 3 | 4 | export default connector(UploadAttachmentButton) 5 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/MembershipRequestsTab/index.js: -------------------------------------------------------------------------------- 1 | import MembershipRequestsTab from './MembershipRequestsTab' 2 | import connector from './MembershipRequestsTab.connector' 3 | export default connector(MembershipRequestsTab) 4 | -------------------------------------------------------------------------------- /src/components/PostCard/Feature/Feature.scss: -------------------------------------------------------------------------------- 1 | .video { 2 | position: relative; 3 | display: flex; 4 | width: 100vw; 5 | height: 100vh; 6 | overflow: hidden; 7 | padding: 0 1rem; 8 | margin-bottom: 1em; 9 | } 10 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/NotificationsDropdown/index.js: -------------------------------------------------------------------------------- 1 | import component from './NotificationsDropdown' 2 | import connector from './NotificationsDropdown.connector' 3 | 4 | export default connector(component) 5 | -------------------------------------------------------------------------------- /src/components/UploadAttachmentButton/UploadAttachmentButton.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import uploadAttachment from 'store/actions/uploadAttachment' 3 | 4 | export default connect(null, { uploadAttachment }) 5 | -------------------------------------------------------------------------------- /src/store/actions/fetchTopic.test.js: -------------------------------------------------------------------------------- 1 | import fetchTopic from './fetchTopic' 2 | 3 | describe('fetchTopic', () => { 4 | it('should match latest snapshot', () => { 5 | expect(fetchTopic('petitions')).toMatchSnapshot() 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | API_HOST=http://localhost:3001 2 | SOCKET_HOST=http://localhost:3001 3 | FILEPICKER_API_KEY= 4 | MIXPANEL_TOKEN= 5 | INTERCOM_APP_ID= 6 | PROXY_HOST=http://hylo-landing.surge.sh 7 | MAPBOX_TOKEN= 8 | HYLO_COOKIE_NAME=InsecureCookieName -------------------------------------------------------------------------------- /graphql.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": "http://localhost:3001/noo/graphql", 3 | "extensions": { 4 | "endpoints": { 5 | "default": { 6 | "url": "http://localhost:3001/noo/graphql" 7 | } 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/GroupsSelector/sampleGroup.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { id: 1, name: 'Stop Kinder Morgan' }, 3 | { id: 2, name: 'David Suzuki Foundation' }, 4 | { id: 3, name: 'Hylo' }, 5 | { id: 4, name: 'Test Group Really Long Name' } 6 | ] 7 | -------------------------------------------------------------------------------- /src/components/EmojiRow/EmojiRow.scss: -------------------------------------------------------------------------------- 1 | .footer-reactions { 2 | transition: all .25s ease; 3 | display: flex; 4 | position: relative; 5 | align-items: center; 6 | padding-bottom: 8px; 7 | height: auto; 8 | flex-wrap: wrap; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/PostCard/index.js: -------------------------------------------------------------------------------- 1 | import component from './PostCard' 2 | import connector from './PostCard.connector' 3 | 4 | export { PostHeader, PostBody, PostFooter, PostGroups, EventBody } from './PostCard' 5 | export default connector(component) 6 | -------------------------------------------------------------------------------- /src/routes/Events/Events.store.test.js: -------------------------------------------------------------------------------- 1 | import { updateTimeframe } from './Events.store' 2 | 3 | describe('updateTimeframe', () => { 4 | it('should match latest snapshot', () => { 5 | expect(updateTimeframe('past')).toMatchSnapshot() 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /src/components/KeyControlledList/KeyControlledItemList.scss: -------------------------------------------------------------------------------- 1 | .keyListPrivacyIcon { 2 | font-size: 14px; 3 | } 4 | 5 | .keyListMemberCount { 6 | color: $color-rhino-50; 7 | font-size: 12px; 8 | display: flex; 9 | justify-content: space-between; 10 | } -------------------------------------------------------------------------------- /src/components/Loading/Loading.test.js: -------------------------------------------------------------------------------- 1 | import Loading from './Loading' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('does something', () => { 6 | shallow() 7 | // expect(wrapper.find('element')).toBeTruthy() 8 | }) 9 | -------------------------------------------------------------------------------- /src/components/Widget/AtAGlanceWidget/AtAGlanceWidget.scss: -------------------------------------------------------------------------------- 1 | .at-a-glance-container{ 2 | display: block; 3 | text-align: left; 4 | font-family: Circular Std; 5 | font-size: 16px; 6 | font-weight: 400; 7 | line-height: 20px; 8 | letter-spacing: 0em; 9 | } -------------------------------------------------------------------------------- /src/router/RedirectRoute.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Redirect, Route } from 'react-router' 3 | 4 | export default function RedirectRoute ({ to, ...routeProps }) { 5 | return } /> 6 | } 7 | -------------------------------------------------------------------------------- /src/routes/AllTopics/AllTopics.store.test.js: -------------------------------------------------------------------------------- 1 | import { deleteGroupTopic } from './AllTopics.store' 2 | 3 | describe('deleteGroupTopic', () => { 4 | it('should match latest snapshot', () => { 5 | expect(deleteGroupTopic(135)).toMatchSnapshot() 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /src/routes/Events/__snapshots__/Events.store.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`updateTimeframe should match latest snapshot 1`] = ` 4 | Object { 5 | "payload": "past", 6 | "type": "Events/UPDATE_TIMEFRAME", 7 | } 8 | `; 9 | -------------------------------------------------------------------------------- /src/store/actions/logout.js: -------------------------------------------------------------------------------- 1 | import { LOGOUT } from 'store/constants' 2 | 3 | export default function logout () { 4 | return { 5 | type: LOGOUT, 6 | payload: { 7 | api: { path: '/noo/session', method: 'DELETE' } 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/util/debounced.js: -------------------------------------------------------------------------------- 1 | import debounce from 'lodash/fp/debounce' 2 | 3 | export const DEFAULT_DEBOUNCE_DELAY = 250 4 | 5 | export const debounced = debounce(DEFAULT_DEBOUNCE_DELAY, (debouncedFun, params) => debouncedFun(params)) 6 | 7 | export default debounced 8 | -------------------------------------------------------------------------------- /scripts/templates/Component.test.js: -------------------------------------------------------------------------------- 1 | import Component from './Component' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('does something', () => { 6 | const wrapper = shallow() 7 | expect(wrapper).toMatchSnapshot() 8 | }) 9 | -------------------------------------------------------------------------------- /src/components/FlagContent/FlagContent.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { submitFlagContent } from './FlagContent.store' 3 | 4 | const mapDispatchToProps = { submitFlagContent } 5 | 6 | export default connect(null, mapDispatchToProps) 7 | -------------------------------------------------------------------------------- /src/store/selectors/getRouteParam.js: -------------------------------------------------------------------------------- 1 | const getRouteParam = (key, props, warn = true) => { 2 | if (warn && !props.match) console.warn(`getRouteParam('${key}') missing props.match`) 3 | return props?.match?.params?.[key] 4 | } 5 | 6 | export default getRouteParam 7 | -------------------------------------------------------------------------------- /src/util/url.js: -------------------------------------------------------------------------------- 1 | import { isURL } from 'validator' 2 | 3 | export const sanitizeURL = (url) => { 4 | if (!url) return null 5 | if (isURL(url, { require_protocol: true })) return url 6 | if (isURL(`https://${url}`)) return `https://${url}` 7 | return null 8 | } 9 | -------------------------------------------------------------------------------- /src/components/CreateGroup/__snapshots__/CreateGroup.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`CreateGroup Allows for passing in initial name and slug via query parameters 1`] = `""`; 4 | 5 | exports[`CreateGroup matches snapshot 1`] = `""`; 6 | -------------------------------------------------------------------------------- /src/store/actions/fetchGroupTopic.test.js: -------------------------------------------------------------------------------- 1 | import fetchGroupTopic from './fetchGroupTopic' 2 | 3 | describe('fetchGroupTopic', () => { 4 | it('should match latest snapshot', () => { 5 | expect(fetchGroupTopic('petitions', 'goteam')).toMatchSnapshot() 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | eslint: 3 | enabled: true 4 | duplication: 5 | enabled: true 6 | config: 7 | languages: 8 | - javascript 9 | ratings: 10 | paths: 11 | - src/** 12 | exclude_paths: 13 | - "**/*.test.js" 14 | - "**/*.scss" 15 | -------------------------------------------------------------------------------- /src/routes/PostDetail/Comments/index.js: -------------------------------------------------------------------------------- 1 | import { withResizeDetector } from 'react-resize-detector' 2 | import component from './Comments' 3 | import connector from './Comments.connector' 4 | 5 | export default connector(withResizeDetector(component, { handleHeight: false })) 6 | -------------------------------------------------------------------------------- /src/store/actions/setReturnToPath.js: -------------------------------------------------------------------------------- 1 | import { SET_RETURN_TO_PATH } from 'store/constants' 2 | 3 | export default function setReturnToPath (returnToPath) { 4 | return { 5 | type: SET_RETURN_TO_PATH, 6 | payload: { 7 | returnToPath 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/components/PeopleTyping/PeopleTyping.test.js: -------------------------------------------------------------------------------- 1 | import PeopleTyping from './PeopleTyping' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('does something', () => { 6 | shallow() 7 | // expect(wrapper.find('element')).toBeTruthy() 8 | }) 9 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/Navigation/TopicNavigation/index.js: -------------------------------------------------------------------------------- 1 | import TopicNavigation from './TopicNavigation' 2 | import connector from './TopicNavigation.connector' 3 | import { withRouter } from 'react-router-dom' 4 | export default withRouter(connector(TopicNavigation)) 5 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Signup/Signup.store.test.js: -------------------------------------------------------------------------------- 1 | import { register } from './Signup.store' 2 | 3 | describe('register', () => { 4 | it('should match latest snapshot', () => { 5 | expect(register('name', 'test@hylo.com', 'testPassword')).toMatchSnapshot() 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /src/store/presenters/presentTopic.js: -------------------------------------------------------------------------------- 1 | export default function presentTopic (topic) { 2 | if (!topic) return null 3 | 4 | return { 5 | ...topic.ref, 6 | label: topic.name, 7 | value: topic.name, 8 | groupTopics: topic.groupTopics.toModelArray() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/store/reducers/mixpanel.js: -------------------------------------------------------------------------------- 1 | import mixpanel from 'mixpanel-browser' 2 | import config, { isProduction, isTest } from 'config' 3 | 4 | if (!isTest) { 5 | mixpanel.init(config.mixpanel.token, { debug: !isProduction }) 6 | } 7 | 8 | export default (state = mixpanel, action) => state 9 | -------------------------------------------------------------------------------- /src/store/selectors/getBlockedUsers.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect' 2 | import { get } from 'lodash/fp' 3 | import getMe from './getMe' 4 | 5 | export default createSelector( 6 | getMe, 7 | me => get('blockedUsers', me) ? get('blockedUsers', me).toRefArray() : [] 8 | ) 9 | -------------------------------------------------------------------------------- /src/store/selectors/getMe.js: -------------------------------------------------------------------------------- 1 | import orm from '../models' 2 | import { createSelector as ormCreateSelector } from 'redux-orm' 3 | 4 | const getMe = ormCreateSelector( 5 | orm, 6 | session => { 7 | return session.Me.first() 8 | } 9 | ) 10 | 11 | export default getMe 12 | -------------------------------------------------------------------------------- /src/components/PostCard/__snapshots__/PostCard.connector.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`mapDispatchToProps 1`] = ` 4 | Object { 5 | "editPost": [Function], 6 | "respondToEvent": [Function], 7 | "showDetails": [Function], 8 | } 9 | `; 10 | -------------------------------------------------------------------------------- /src/util/mobile.test.js: -------------------------------------------------------------------------------- 1 | import { mobileRedirect } from './mobile' 2 | 3 | jest.mock('ismobilejs', () => ({ 4 | apple: { 5 | device: true, 6 | phone: true 7 | } 8 | })) 9 | 10 | it('returns truthy if mobile', () => { 11 | expect(mobileRedirect()).toBeTruthy() 12 | }) 13 | -------------------------------------------------------------------------------- /src/components/EventInviteDialog/EventInviteDialog.store.test.js: -------------------------------------------------------------------------------- 1 | import { invitePeopleToEvent } from './EventInviteDialog.store' 2 | 3 | describe('invitePeopleToEvent', () => { 4 | it('matches snapshot', () => { 5 | expect(invitePeopleToEvent(1, [2, 3, 4])).toMatchSnapshot() 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/SettingsSection/SettingsSection.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './SettingsSection.scss' 3 | 4 | const SettingsSection = ({ children }) => ( 5 |
6 | {children} 7 |
8 | ) 9 | 10 | export default SettingsSection 11 | -------------------------------------------------------------------------------- /apollo.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | client: { 3 | includes: ['./**/*.js'], 4 | excludes: ['./**/*.js.test'], 5 | service: { 6 | name: 'local Hylo GraphQL', 7 | url: 'http://localhost:3001/noo/graphql', 8 | skipSSLValidation: true 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberPosts/MemberPosts.scss: -------------------------------------------------------------------------------- 1 | .subhead { 2 | composes: hdr-headline from 'css/typography.scss'; 3 | margin: $space-8x 0 $space-6x 0; 4 | } 5 | 6 | .activity-item { 7 | margin: $space-5x 0; 8 | 9 | a:first-child { 10 | text-decoration: none; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberVotes/MemberVotes.scss: -------------------------------------------------------------------------------- 1 | .subhead { 2 | composes: hdr-headline from 'css/typography.scss'; 3 | margin: $space-8x 0 $space-6x 0; 4 | } 5 | 6 | .activity-item { 7 | margin: $space-5x 0; 8 | 9 | a:first-child { 10 | text-decoration: none; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /public/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | #ffffff -------------------------------------------------------------------------------- /src/store/presenters/presentGroupInvite.js: -------------------------------------------------------------------------------- 1 | export default function presentGroupInvite (invite) { 2 | if (!invite) return null 3 | 4 | return { 5 | ...invite.ref, 6 | creator: invite.creator ? invite.creator.ref : null, 7 | group: invite.group ? invite.group.ref : null 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberComments/MemberComments.scss: -------------------------------------------------------------------------------- 1 | .subhead { 2 | composes: hdr-headline from 'css/typography.scss'; 3 | margin: $space-8x 0 $space-6x 0; 4 | } 5 | 6 | .activity-item { 7 | margin: $space-5x 0; 8 | 9 | a:first-child { 10 | text-decoration: none; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberVotes/index.js: -------------------------------------------------------------------------------- 1 | import MemberVotes from './MemberVotes' // TODO REACTIONS: switch this to reactions 2 | import connector from './MemberVotes.connector' // TODO REACTIONS: switch this to reactions 3 | export default connector(MemberVotes) // TODO REACTIONS: switch this to reactions 4 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/PasswordReset/PasswordReset.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import sendPasswordReset from 'store/actions/sendPasswordReset' 3 | 4 | export const mapDispatchToProps = { 5 | sendPasswordReset 6 | } 7 | 8 | export default connect(null, mapDispatchToProps) 9 | -------------------------------------------------------------------------------- /src/store/reducers/ormReducer/clearCacheFor.js: -------------------------------------------------------------------------------- 1 | export default function clearCacheFor (ormModel, id) { 2 | const modelInstance = ormModel.withId(id) 3 | // this line is to clear the selector memoization 4 | modelInstance && modelInstance.update({ _invalidate: (modelInstance._invalidate || 0) + 1 }) 5 | } 6 | -------------------------------------------------------------------------------- /src/components/FlagContent/FlagContent.store.test.js: -------------------------------------------------------------------------------- 1 | import { submitFlagContent } from './FlagContent.store' 2 | 3 | describe('flagContent', () => { 4 | it('should match the last snapshot', () => { 5 | expect(submitFlagContent('other', 'A Reason', { id: 22, type: 'post' })).toMatchSnapshot() 6 | }) 7 | }) 8 | -------------------------------------------------------------------------------- /src/components/TopicSupportComingSoon/TopicSupportComingSoon.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { shallow } from 'enzyme' 3 | import TopicSupportComingSoon from './index' 4 | 5 | it('renders', () => { 6 | const wrapper = shallow() 7 | expect(wrapper).toMatchSnapshot() 8 | }) 9 | -------------------------------------------------------------------------------- /src/routes/OAuth/Login/Login.store.js: -------------------------------------------------------------------------------- 1 | import { LOGIN } from 'store/constants' 2 | 3 | export function login (uid, email, password) { 4 | return { 5 | type: LOGIN, 6 | payload: { 7 | api: { method: 'post', path: `/noo/oidc/${uid}/login`, params: { email, password } } 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/store/actions/deleteMe.js: -------------------------------------------------------------------------------- 1 | import { DELETE_ME } from '../constants' 2 | 3 | export default function deleteMe () { 4 | return { 5 | type: DELETE_ME, 6 | graphql: { 7 | query: `mutation { 8 | deleteMe { 9 | success 10 | } 11 | }` 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/routes/PostDetail/__snapshots__/PostDetail.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`PostDetail renders correctly 1`] = ` 4 | 9 | 10 | 11 | `; 12 | -------------------------------------------------------------------------------- /src/store/models/Skill.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | class Skill extends Model { 4 | toString () { 5 | return `Skill: ${this.name}` 6 | } 7 | } 8 | 9 | export default Skill 10 | 11 | Skill.modelName = 'Skill' 12 | 13 | Skill.fields = { 14 | id: attr(), 15 | name: attr() 16 | } 17 | -------------------------------------------------------------------------------- /src/store/selectors/getCommonRoles.js: -------------------------------------------------------------------------------- 1 | import orm from '../models' 2 | import { createSelector as ormCreateSelector } from 'redux-orm' 3 | 4 | const getCommonRoles = ormCreateSelector( 5 | orm, 6 | session => { 7 | return session.CommonRole.all().toRefArray() 8 | } 9 | ) 10 | 11 | export default getCommonRoles 12 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/WelcomeExplore/WelcomeExplore.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import getMe from 'store/selectors/getMe' 3 | 4 | export function mapStateToProps (state, props) { 5 | return { 6 | currentUser: getMe(state) 7 | } 8 | } 9 | 10 | export default connect(mapStateToProps) 11 | -------------------------------------------------------------------------------- /src/store/actions/deactivateMe.js: -------------------------------------------------------------------------------- 1 | import { DEACTIVATE_ME } from '../constants' 2 | 3 | export default function deactivateMe () { 4 | return { 5 | type: DEACTIVATE_ME, 6 | graphql: { 7 | query: `mutation { 8 | deactivateMe { 9 | success 10 | } 11 | }` 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/store/actions/resetNewPostCount.test.js: -------------------------------------------------------------------------------- 1 | import resetNewPostCount from './resetNewPostCount' 2 | 3 | it('works for GroupTopic', () => { 4 | expect(resetNewPostCount(5, 'GroupTopic')).toMatchSnapshot() 5 | }) 6 | 7 | it('works for Membership', () => { 8 | expect(resetNewPostCount(5, 'Membership')).toMatchSnapshot() 9 | }) 10 | -------------------------------------------------------------------------------- /src/store/reducers/util.js: -------------------------------------------------------------------------------- 1 | import { SET_STATE } from 'store/constants' 2 | 3 | export const composeReducers = (...reducers) => (state, action) => 4 | reducers.reduce((newState, reducer) => reducer(newState, action), state) 5 | 6 | export const handleSetState = (state = {}, { type, payload }) => 7 | type === SET_STATE ? payload : state 8 | -------------------------------------------------------------------------------- /src/graphql/fragments/GroupTopicsFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment GroupTopicsFragment on GroupTopicQuerySet { 2 | hasMore 3 | total 4 | items { 5 | id 6 | postsTotal 7 | followersTotal 8 | isSubscribed 9 | lastReadPostId 10 | newPostCount 11 | topic { 12 | id 13 | name 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/store/models/LinkPreview.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | class LinkPreview extends Model { 4 | toString () { 5 | return `LinkPreview: ${this.title}` 6 | } 7 | } 8 | 9 | export default LinkPreview 10 | 11 | LinkPreview.modelName = 'LinkPreview' 12 | 13 | LinkPreview.fields = { 14 | id: attr() 15 | } 16 | -------------------------------------------------------------------------------- /src/components/CheckBox/CheckBox.test.js: -------------------------------------------------------------------------------- 1 | import CheckBox from './CheckBox' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('renders correctly', () => { 6 | const wrapper = shallow( {}} 9 | className='box' />) 10 | expect(wrapper).toMatchSnapshot() 11 | }) 12 | -------------------------------------------------------------------------------- /src/store/actions/trackAnalyticsEvent.js: -------------------------------------------------------------------------------- 1 | import { TRACK_ANALYTICS_EVENT } from 'store/constants' 2 | 3 | export default function trackAnalyticsEvent (eventName, data) { 4 | return { 5 | type: TRACK_ANALYTICS_EVENT, 6 | meta: { 7 | analytics: { 8 | eventName, 9 | ...data 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/PostCard/Feature/Feature.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactPlayer from 'react-player' 3 | import './Feature.scss' 4 | 5 | export default function Feature ({ url }) { 6 | return ( 7 | 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/store/selectors/getMySkills.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | 4 | const getMySkills = createSelector( 5 | orm, 6 | (session) => { 7 | const me = session.Me.first() 8 | if (!me) return [] 9 | return me.skills.toRefArray() 10 | } 11 | ) 12 | 13 | export default getMySkills 14 | -------------------------------------------------------------------------------- /src/components/UploadAttachmentButton/UploadAttachmentButton.scss: -------------------------------------------------------------------------------- 1 | .button { 2 | cursor: pointer; 3 | &:hover { 4 | .icon { 5 | opacity: 0.85; 6 | } 7 | } 8 | } 9 | 10 | .icon { 11 | cursor: pointer; 12 | opacity: 0.5; 13 | font-size: 30px; 14 | color: $color-white; 15 | text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5); 16 | } 17 | -------------------------------------------------------------------------------- /src/store/selectors/getPlatformAgreements.js: -------------------------------------------------------------------------------- 1 | import orm from '../models' 2 | import { createSelector as ormCreateSelector } from 'redux-orm' 3 | 4 | const getPlatformAgreements = ormCreateSelector( 5 | orm, 6 | session => { 7 | return session.PlatformAgreement.all().toRefArray() 8 | } 9 | ) 10 | 11 | export default getPlatformAgreements 12 | -------------------------------------------------------------------------------- /src/store/selectors/getPostById.js: -------------------------------------------------------------------------------- 1 | import { createSelector as ormCreateSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | 4 | // protest selector 5 | const getPostById = ormCreateSelector( 6 | orm, 7 | (state, id) => id, 8 | ({ Post }, id) => { 9 | return Post.withId(id) 10 | } 11 | ) 12 | 13 | export default getPostById 14 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/AddLocation/AddLocation.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { shallow } from 'enzyme' 3 | import AddLocation from './AddLocation' 4 | 5 | describe('AddLocation', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow() 8 | expect(wrapper).toMatchSnapshot() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/UploadPhoto/UploadPhoto.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { shallow } from 'enzyme' 3 | import UploadPhoto from './UploadPhoto' 4 | 5 | describe('UploadPhoto', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow() 8 | expect(wrapper).toMatchSnapshot() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /src/components/HyloHTML/HyloHTML.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export default function HyloHTML ({ 4 | html, 5 | element = 'div', 6 | ...props 7 | }) { 8 | return ( 9 | React.createElement( 10 | element, 11 | { 12 | ...props, 13 | dangerouslySetInnerHTML: { __html: html } 14 | } 15 | ) 16 | ) 17 | } 18 | -------------------------------------------------------------------------------- /src/store/selectors/getPerson.js: -------------------------------------------------------------------------------- 1 | import { createSelector as ormCreateSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | 4 | const getPerson = ormCreateSelector( 5 | orm, 6 | (state, props) => props.personId, 7 | ({ Person }, personId) => Person.idExists(personId) ? Person.withId(personId) : null 8 | ) 9 | 10 | export default getPerson 11 | -------------------------------------------------------------------------------- /scripts/templates/Component.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types' 2 | import React from 'react' 3 | import './ReplaceComponent.scss' 4 | 5 | const { string } = PropTypes 6 | 7 | export default function ReplaceComponent ({ example }) { 8 | return
{example}
9 | } 10 | ReplaceComponent.propTypes = { 11 | example: string 12 | } 13 | -------------------------------------------------------------------------------- /src/components/CreateGroup/__snapshots__/CreateGroup.connector.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`CreateGroup.connector mapDispatchToProps maps the action generators 1`] = ` 4 | Object { 5 | "createGroup": [Function], 6 | "fetchGroupExists": [Function], 7 | "goBack": [Function], 8 | "goToGroup": [Function], 9 | } 10 | `; 11 | -------------------------------------------------------------------------------- /src/components/Map/Map.scss: -------------------------------------------------------------------------------- 1 | .tooltip { 2 | position: absolute; 3 | z-index: 0; 4 | pointerEvents: none; 5 | border-radius: 4px; 6 | background-color: white; 7 | padding: 0 15px; 8 | color: rgba(87, 102, 123, 1.000); 9 | box-shadow: $box-shadow-default; 10 | line-height: 28px; 11 | 12 | p { 13 | margin: 0; 14 | padding: 0; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /scripts/generate.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const program = require('commander') 3 | 4 | program 5 | .version('0.0.1') 6 | .command('component [ComponentName]', 'create a new component') 7 | .command('store [ComponentName]', 'add a store file for an existing component') 8 | .command('model [ModelName]', 'coming soon to a cli near you!') 9 | .parse(process.argv) 10 | -------------------------------------------------------------------------------- /src/components/RoundImageRow/RoundImageRow.test.js: -------------------------------------------------------------------------------- 1 | import RoundImageRow from './RoundImageRow' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('displays a RoundImage for every url', () => { 6 | const wrapper = shallow() 7 | expect(wrapper.find('RoundImage').length).toEqual(4) 8 | }) 9 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Login/Login.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render, screen } from 'util/testing/reactTestingLibraryExtended' 3 | import Login from './Login' 4 | 5 | it('renders correctly', () => { 6 | render( 7 | 8 | ) 9 | 10 | expect(screen.getByText('Sign in to Hylo')).toBeInTheDocument() 11 | }) 12 | -------------------------------------------------------------------------------- /src/components/Badge/Badge.test.js: -------------------------------------------------------------------------------- 1 | import Badge from './component' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('matches the last snapshot', () => { 6 | const props = { 7 | number: 7, 8 | expanded: true, 9 | onClick: () => {} 10 | } 11 | const wrapper = shallow() 12 | expect(wrapper).toMatchSnapshot() 13 | }) 14 | -------------------------------------------------------------------------------- /src/util/generateTempId.js: -------------------------------------------------------------------------------- 1 | export default function generateTempID (length = 12) { 2 | const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789' 3 | let result = '' 4 | for (let i = 0; i < length; i++) { 5 | const randomIndex = Math.floor(Math.random() * characters.length) 6 | result += characters[randomIndex] 7 | } 8 | return result 9 | } 10 | -------------------------------------------------------------------------------- /src/util/testing/extractModelsForTest.js: -------------------------------------------------------------------------------- 1 | import extractModelsFromAction from 'store/reducers/ModelExtractor/extractModelsFromAction' 2 | 3 | export default function extractModelsForTest (data, extractModel = {}, ormSession) { 4 | extractModelsFromAction({ 5 | payload: { 6 | data 7 | }, 8 | meta: { 9 | extractModel 10 | } 11 | }, ormSession) 12 | } 13 | -------------------------------------------------------------------------------- /src/components/PostCard/PostCard.connector.test.js: -------------------------------------------------------------------------------- 1 | import { mapDispatchToProps } from './PostCard.connector' 2 | 3 | describe('mapDispatchToProps', () => { 4 | it('', () => { 5 | const props = { 6 | post: { 7 | id: 1 8 | } 9 | } 10 | const dispatchProps = mapDispatchToProps({}, props) 11 | expect(dispatchProps).toMatchSnapshot() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /src/store/actions/fetchPerson.js: -------------------------------------------------------------------------------- 1 | import { FETCH_PERSON } from 'store/constants' 2 | import personQuery from 'graphql/queries/personQuery' 3 | 4 | export default function fetchPerson (id, query = personQuery) { 5 | return { 6 | type: FETCH_PERSON, 7 | graphql: { 8 | query, 9 | variables: { id } 10 | }, 11 | meta: { extractModel: 'Person' } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/components/CreateTopic/CreateTopic.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | 3 | import { MODULE_NAME, fetchGroupTopic, createTopic } from './CreateTopic.store' 4 | 5 | const mapStateToProps = (state, props) => { 6 | return { 7 | groupTopicExists: state[MODULE_NAME] 8 | } 9 | } 10 | 11 | export default connect(mapStateToProps, { createTopic, fetchGroupTopic }) 12 | -------------------------------------------------------------------------------- /src/components/Widget/PrivacyWidget/PrivacyWidget.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useTranslation } from 'react-i18next' 3 | 4 | import './Privacy.scss' 5 | 6 | export default function PrivacyWidget (props) { 7 | const { t } = useTranslation() 8 | 9 | return ( 10 |
11 | {t('group privacy settings')} 12 |
13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/components/Widget/StewardsWidget/StewardsWidget.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | import { useTranslation } from 'react-i18next' 4 | import './StewardsWidget.scss' 5 | 6 | export default function StewardsWidget (props) { 7 | const { t } = useTranslation() 8 | 9 | return ( 10 |
11 | {t('The stewards go here')} 12 |
13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/store/presenters/presentComment.js: -------------------------------------------------------------------------------- 1 | export default function presentComment (comment, groupSlug = undefined) { 2 | if (!comment || !comment.post) return 3 | return { 4 | ...comment.ref, 5 | creator: comment.creator.ref, 6 | post: comment.post.ref, 7 | attachments: comment.attachments 8 | .orderBy('position').toModelArray(), 9 | slug: groupSlug 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/components/TextInput/TextInput.test.js: -------------------------------------------------------------------------------- 1 | import TextInput from './TextInput' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | describe('TextInput', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow( {}} 9 | value={'value'} 10 | />) 11 | expect(wrapper).toMatchSnapshot() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/PasswordReset/PasswordReset.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { shallow } from 'enzyme' 3 | import PasswordReset from './PasswordReset' 4 | 5 | describe('Signup', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow(, { disableLifecycleMethods: true }) 8 | expect(wrapper).toMatchSnapshot() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Signup/Signup.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render, screen } from 'util/testing/reactTestingLibraryExtended' 3 | import Signup from './Signup' 4 | 5 | it('renders correctly', () => { 6 | render( 7 | 8 | ) 9 | 10 | expect(screen.getByText('Enter your email to get started:')).toBeInTheDocument() 11 | }) 12 | -------------------------------------------------------------------------------- /src/routes/OAuth/Login/Login.test.js: -------------------------------------------------------------------------------- 1 | import Login from './Login' 2 | import { render, screen } from 'util/testing/reactTestingLibraryExtended' 3 | import React from 'react' 4 | 5 | it('renders correctly', () => { 6 | render( 7 | 8 | ) 9 | 10 | expect(screen.getByText('Sign in to Hylo')).toBeInTheDocument() 11 | }) 12 | -------------------------------------------------------------------------------- /src/store/middleware/pendingMiddleware.js: -------------------------------------------------------------------------------- 1 | import { isPromise } from 'util/index' 2 | 3 | export default function pendingMiddleware (store) { 4 | return next => action => { 5 | const { type, payload } = action 6 | 7 | if (isPromise(payload)) { 8 | store.dispatch({ ...action, type: type + '_PENDING', payload: null }) 9 | } 10 | 11 | return next(action) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/client/util.js: -------------------------------------------------------------------------------- 1 | // This is the id of the root element in the index.html file 2 | export const rootDomId = 'root' 3 | 4 | export const loadScript = url => { 5 | var script = document.createElement('script') 6 | script.src = url 7 | const promise = new Promise((resolve, reject) => { 8 | script.onload = resolve 9 | }) 10 | document.head.appendChild(script) 11 | return promise 12 | } 13 | -------------------------------------------------------------------------------- /src/components/CheckBox/CheckBox.scss: -------------------------------------------------------------------------------- 1 | .checkbox { 2 | visibility: hidden; 3 | width: 0; 4 | } 5 | 6 | .label { 7 | margin-bottom: 0; 8 | cursor: pointer; 9 | } 10 | 11 | .label-left { 12 | padding-left: 8px; 13 | } 14 | 15 | .icon { 16 | color: $color-caribbean-green; 17 | &:hover { 18 | color: $color-gossamer; 19 | } 20 | vertical-align: sub; 21 | padding-right: 8px; 22 | } 23 | -------------------------------------------------------------------------------- /src/routes/GroupSidebar/__snapshots__/GroupSidebar.connector.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`mapStateToProps returns the right keys 1`] = ` 4 | Object { 5 | "group": Object { 6 | "id": "88", 7 | "slug": "bar", 8 | }, 9 | "members": Array [], 10 | "myResponsibilities": Array [], 11 | "slug": "bar", 12 | "stewards": Array [], 13 | } 14 | `; 15 | -------------------------------------------------------------------------------- /src/store/selectors/getMyJoinRequests.js: -------------------------------------------------------------------------------- 1 | import { createSelector as ormCreateSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | 4 | const getMyJoinRequests = ormCreateSelector( 5 | orm, 6 | ({ Me, JoinRequest }) => { 7 | const me = Me.first() 8 | if (!me) return [] 9 | return me.joinRequests.toModelArray() 10 | } 11 | ) 12 | 13 | export default getMyJoinRequests 14 | -------------------------------------------------------------------------------- /scripts/templates/Component.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | // import getMe from 'store/selectors/getMe' 3 | 4 | export function mapStateToProps (state, props) { 5 | return { 6 | example: 'example' 7 | // currentUser: getMe(state, props) 8 | } 9 | } 10 | 11 | export const mapDispatchToProps = {} 12 | 13 | export default connect(mapStateToProps, mapDispatchToProps) 14 | -------------------------------------------------------------------------------- /src/components/Icon/Icon.scss: -------------------------------------------------------------------------------- 1 | .icon { 2 | color: $color-rhino-60; 3 | font-size: 24px; 4 | position: relative; 5 | } 6 | 7 | .green { 8 | color: $color-caribbean-green; 9 | } 10 | 11 | .blue { 12 | color: $color-picton-blue; 13 | } 14 | 15 | :global { 16 | .icon-More { 17 | position: relative; 18 | top: 3px; 19 | } 20 | .icon-Replies { 21 | font-size: 17px; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/components/Member/__snapshots__/Member.connector.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`mapDispatchToProps goToPerson is correct for "groups" context 1`] = ` 4 | Object { 5 | "payload": Object { 6 | "args": Array [ 7 | "/groups/anything/members/1", 8 | ], 9 | "method": "push", 10 | }, 11 | "type": "@@router/CALL_HISTORY_METHOD", 12 | } 13 | `; 14 | -------------------------------------------------------------------------------- /src/components/ModalDialog/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ModalDialog from './ModalDialog' 3 | import ReactDOM from 'react-dom' 4 | import { rootDomId } from 'client/util' 5 | 6 | export default function ModalDialogPortal (props) { 7 | return ReactDOM.createPortal( 8 | {props.children}, 9 | document.getElementById(rootDomId) 10 | ) 11 | } 12 | -------------------------------------------------------------------------------- /src/components/PostCard/PostTitle/__snapshots__/PostTitle.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`matches last snapshot 1`] = ` 4 | 9 |
13 | hello there 14 |
15 |
16 | `; 17 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/WelcomeExplore/WelcomeExplore.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { shallow } from 'enzyme' 3 | import WelcomeExplore from './WelcomeExplore' 4 | 5 | describe('WelcomeExplore', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow() 8 | expect(wrapper).toMatchSnapshot() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /src/components/Badge/__snapshots__/Badge.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`matches the last snapshot 1`] = ` 4 | 8 | 11 | 14 | 7 15 | 16 | 17 | 18 | `; 19 | -------------------------------------------------------------------------------- /src/components/Pillbox/Pillbox.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { shallow } from 'enzyme' 3 | import Pillbox from './Pillbox' 4 | 5 | describe('Pillbox', () => { 6 | it('renders', () => { 7 | const wrapper = shallow() 11 | expect(wrapper).toMatchSnapshot() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /src/css/global/index.scss: -------------------------------------------------------------------------------- 1 | // NOTE: font-face declarations need to be outside 2 | // of CSS Modules global calls. 3 | // ref: https://github.com/css-modules/css-modules/issues/95 4 | @import './fonts'; 5 | 6 | :global { 7 | @import './bootstrap'; 8 | @import './icons'; 9 | @import '../typography'; 10 | @import '../datepicker'; 11 | 12 | body { 13 | overflow-x: hidden; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/LoadingItems/LoadingItems.scss: -------------------------------------------------------------------------------- 1 | .loader { 2 | height: $messages-body-height; 3 | 4 | .loader-image { 5 | background: no-repeat center; 6 | height: 352px; 7 | background-size: 250px; 8 | } 9 | .loader-animation { 10 | width: 39px; 11 | height: 20px; 12 | position: absolute; 13 | top: 112px; 14 | left: 177px; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/store/selectors/getGroupForCurrentRoute.js: -------------------------------------------------------------------------------- 1 | import orm from 'store/models' 2 | import { createSelector as ormCreateSelector } from 'redux-orm' 3 | import { getSlugFromLocation } from './isGroupRoute' 4 | 5 | const getGroupForCurrentRoute = ormCreateSelector( 6 | orm, 7 | getSlugFromLocation, 8 | (session, slug) => session.Group.safeGet({ slug }) 9 | ) 10 | 11 | export default getGroupForCurrentRoute 12 | -------------------------------------------------------------------------------- /src/components/FlagContent/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import FlagContent from './FlagContent' 3 | import ReactDOM from 'react-dom' 4 | import { rootDomId } from 'client/util' 5 | 6 | const FlagContentPortal = function (props) { 7 | return ReactDOM.createPortal( 8 | , 9 | document.getElementById(rootDomId) 10 | ) 11 | } 12 | 13 | export default FlagContentPortal 14 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/NoItems/NoItems.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { bgImageStyle } from 'util/index' 3 | import './NoItems.scss' 4 | 5 | export default function NoItems ({ message }) { 6 | return ( 7 |
8 |

{message}

9 |
10 |
11 | ) 12 | } 13 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/ExportDataTab/ExportDataTab.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | // empty 3 | } 4 | 5 | .title { 6 | composes: hdr-display from 'css/typography.scss'; 7 | margin-bottom: 10px; 8 | padding: 0 9 | } 10 | 11 | .subtitle { 12 | composes: hdr-headline from 'css/typography.scss'; 13 | color: $color-rhino-80; 14 | } 15 | 16 | .help { 17 | color: $color-rhino-60; 18 | margin-bottom: 16px; 19 | } 20 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/RecentActivity/RecentActivity.scss: -------------------------------------------------------------------------------- 1 | .subhead { 2 | composes: hdr-headline from 'css/typography.scss'; 3 | margin: $space-8x 0 $space-6x 0; 4 | } 5 | 6 | .activity-item { 7 | margin: 20px 0; 8 | background-color: rgba(255,255,255,1); 9 | border-radius: 5px; 10 | box-shadow: 0 4px 10px rgb(35 65 90 / 20%); 11 | 12 | a:first-child { 13 | text-decoration: none; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/store/models/Widget.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | class Widget extends Model { 4 | toString () { 5 | return `Widget: ${this.name}` 6 | } 7 | } 8 | 9 | export default Widget 10 | 11 | Widget.modelName = 'Widget' 12 | 13 | Widget.fields = { 14 | id: attr(), 15 | name: attr(), 16 | isVisible: attr(), 17 | order: attr(), 18 | context: attr(), 19 | settings: attr() 20 | } 21 | -------------------------------------------------------------------------------- /src/store/selectors/getMyMemberships.js: -------------------------------------------------------------------------------- 1 | import { createSelector as ormCreateSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | 4 | const getMyMemberships = ormCreateSelector( 5 | orm, 6 | ({ Me, Membership }) => { 7 | const me = Me.first() 8 | if (!me) return [] 9 | return Membership.filter({ person: me.id }).toModelArray() 10 | } 11 | ) 12 | 13 | export default getMyMemberships 14 | -------------------------------------------------------------------------------- /src/routes/PostDetail/Comments/ShowMore.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './ShowMore.scss' 3 | 4 | export default function ShowMore ({ commentsLength, total, hasMore, fetchComments }) { 5 | if (!hasMore) return null 6 | 7 | const extra = total - commentsLength 8 | 9 | return
10 | View {extra} previous comment{extra > 1 ? 's' : ''} 11 |
12 | } 13 | -------------------------------------------------------------------------------- /src/store/actions/fetchNotificationSettings.js: -------------------------------------------------------------------------------- 1 | import { FETCH_NOTIFICATION_SETTINGS } from 'store/constants' 2 | 3 | export default function fetchNoticationSettings (token) { 4 | return { 5 | type: FETCH_NOTIFICATION_SETTINGS, 6 | payload: { 7 | api: { 8 | path: '/noo/user/notification-settings', 9 | method: 'GET', 10 | params: { token } 11 | } 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/store/models/PostMembership.js: -------------------------------------------------------------------------------- 1 | import { attr, fk, Model } from 'redux-orm' 2 | 3 | class PostMembership extends Model { 4 | toString () { 5 | return `PostMembership: ${this.id}` 6 | } 7 | } 8 | 9 | export default PostMembership 10 | 11 | PostMembership.modelName = 'PostMembership' 12 | PostMembership.fields = { 13 | id: attr(), 14 | pinned: attr(), 15 | group: fk('Group', 'postMemberships') 16 | } 17 | -------------------------------------------------------------------------------- /src/store/reducers/ormReducer/clearCacheFor.test.js: -------------------------------------------------------------------------------- 1 | import clearCacheFor from './clearCacheFor' 2 | 3 | describe('clearCacheFor', () => { 4 | it('runs expected Redux ORM cache clear hack', () => { 5 | const ModelClass = { 6 | withId: jest.fn(() => ModelClass), 7 | update: jest.fn() 8 | } 9 | clearCacheFor(ModelClass, '10') 10 | expect(ModelClass.update).toHaveBeenCalled() 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /src/util/filterDeletedUsers.test.js: -------------------------------------------------------------------------------- 1 | import filterDeletedUsers from './filterDeletedUsers' 2 | 3 | it('Returns true for regular user', () => { 4 | const testUser = { name: 'Flowers' } 5 | expect(filterDeletedUsers(testUser)).toBeTruthy() 6 | }) 7 | 8 | it('Returns false for deleted user', () => { 9 | const deletedUser = { name: 'Deleted User' } 10 | expect(filterDeletedUsers(deletedUser)).toBeFalsy() 11 | }) 12 | -------------------------------------------------------------------------------- /src/util/webView.js: -------------------------------------------------------------------------------- 1 | export function sendMessageToWebView (type, data) { 2 | if (!type) { 3 | throw new Error('Must provide a message `type` when sending a message to the WebView') 4 | } 5 | 6 | isWebView() && window.ReactNativeWebView.postMessage(JSON.stringify({ type, data })) 7 | } 8 | 9 | export default function isWebView () { 10 | return typeof window !== 'undefined' && window.ReactNativeWebView 11 | } 12 | -------------------------------------------------------------------------------- /src/components/PeopleTyping/PeopleTyping.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { clearUserTyping, getPeopleTyping } from './PeopleTyping.store' 3 | 4 | export function mapStateToProps (state, props) { 5 | return { 6 | peopleTyping: getPeopleTyping(state) 7 | } 8 | } 9 | 10 | export const mapDispatchToProps = { clearUserTyping } 11 | 12 | export default connect(mapStateToProps, mapDispatchToProps) 13 | -------------------------------------------------------------------------------- /src/routes/OAuth/Consent/Consent.test.js: -------------------------------------------------------------------------------- 1 | import Consent from './Consent' 2 | import { render, screen } from 'util/testing/reactTestingLibraryExtended' 3 | import React from 'react' 4 | 5 | it('renders correctly', () => { 6 | render( 7 | 8 | ) 9 | 10 | expect(screen.getByText('{{appName}} wants access to your Hylo account')).toBeInTheDocument() 11 | }) 12 | -------------------------------------------------------------------------------- /src/store/actions/joinProject.js: -------------------------------------------------------------------------------- 1 | import { JOIN_PROJECT } from 'store/constants' 2 | 3 | export default function (id) { 4 | return { 5 | type: JOIN_PROJECT, 6 | graphql: { 7 | query: `mutation ($id: ID) { 8 | joinProject (id: $id) { 9 | success 10 | } 11 | }`, 12 | variables: { 13 | id 14 | } 15 | }, 16 | meta: { 17 | id 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/store/models/Agreement.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | class Agreement extends Model { 4 | toString () { 5 | return `Agreement (${this.id}): ${this.title}` 6 | } 7 | } 8 | 9 | export default Agreement 10 | 11 | Agreement.modelName = 'Agreement' 12 | 13 | Agreement.fields = { 14 | id: attr(), 15 | accepted: attr(), 16 | description: attr(), 17 | order: attr(), 18 | title: attr() 19 | } 20 | -------------------------------------------------------------------------------- /src/store/models/PlatformAgreement.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | class PlatformAgreement extends Model { 4 | toString () { 5 | return `PlatformAgreement (${this.id}): ${this.text}` 6 | } 7 | } 8 | 9 | export default PlatformAgreement 10 | 11 | PlatformAgreement.modelName = 'PlatformAgreement' 12 | 13 | PlatformAgreement.fields = { 14 | id: attr(), 15 | type: attr(), 16 | text: attr() 17 | } 18 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es6", 4 | "jsx": "react", 5 | "checkJs": false, 6 | "allowJs": true, 7 | "allowSyntheticDefaultImports": true, 8 | "module": "commonjs", 9 | "baseUrl": ".", 10 | "paths": { 11 | "*": ["src/*"] 12 | }, 13 | "outDir": "build" 14 | }, 15 | "exclude": [ 16 | "node_modules", 17 | "es5", 18 | "build" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /src/components/Button/__snapshots__/Button.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Button renders correctly 1`] = ` 4 |
16 | Log in 17 |
18 | `; 19 | -------------------------------------------------------------------------------- /src/store/actions/leaveProject.js: -------------------------------------------------------------------------------- 1 | import { LEAVE_PROJECT } from 'store/constants' 2 | 3 | export default function (id) { 4 | return { 5 | type: LEAVE_PROJECT, 6 | graphql: { 7 | query: `mutation ($id: ID) { 8 | leaveProject (id: $id) { 9 | success 10 | } 11 | }`, 12 | variables: { 13 | id 14 | } 15 | }, 16 | meta: { 17 | id 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /public/apple-app-site-association: -------------------------------------------------------------------------------- 1 | { 2 | "applinks": { 3 | "apps": [], 4 | "details": [ 5 | { 6 | "appID": "L4KZBPS2F3.com.hylo.HyloA", 7 | "paths": [ 8 | "/noo/login/token", 9 | "/noo/login/jwt", 10 | "NOT /noo/*", 11 | "*" 12 | ] 13 | } 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/store/models/Message.js: -------------------------------------------------------------------------------- 1 | import { attr, fk, Model } from 'redux-orm' 2 | 3 | class Message extends Model { 4 | toString () { 5 | return `Message: ${this.id}` 6 | } 7 | } 8 | 9 | export default Message 10 | 11 | Message.modelName = 'Message' 12 | 13 | Message.fields = { 14 | id: attr(), 15 | text: attr(), 16 | creator: fk('Person'), 17 | createdAt: attr(), 18 | messageThread: fk('MessageThread', 'messages') 19 | } 20 | -------------------------------------------------------------------------------- /src/store/selectors/getQuerystringParam.js: -------------------------------------------------------------------------------- 1 | import { pick } from 'lodash/fp' 2 | import qs from 'querystring' 3 | 4 | const getQuerystringParam = (key, props) => { 5 | if (!props.location) throw new Error(`getQuerystringParam('${key}') missing props.location`) 6 | const query = qs.parse(props.location.search.substring(1)) 7 | return Array.isArray(key) ? pick(key, query) : query[key] 8 | } 9 | 10 | export default getQuerystringParam 11 | -------------------------------------------------------------------------------- /src/components/FlagGroupContent/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import FlagGroupContent from './FlagGroupContent' 3 | import ReactDOM from 'react-dom' 4 | import { rootDomId } from 'client/util' 5 | 6 | const FlagGroupContentPortal = function (props) { 7 | return ReactDOM.createPortal( 8 | , 9 | document.getElementById(rootDomId) 10 | ) 11 | } 12 | 13 | export default FlagGroupContentPortal 14 | -------------------------------------------------------------------------------- /src/components/Switch/Switch.test.js: -------------------------------------------------------------------------------- 1 | import Switch from './Switch' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | describe('Switch', () => { 6 | it('renders correctly', () => { 7 | const props = { 8 | value: true, 9 | onClick: () => {}, 10 | className: 'switch-class' 11 | } 12 | const wrapper = shallow() 13 | expect(wrapper).toMatchSnapshot() 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /src/routes/Messages/CloseMessages/CloseMessages.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { Link } from 'react-router-dom' 3 | import Icon from 'components/Icon' 4 | import './CloseMessages.scss' 5 | 6 | function CloseMessages ({ onCloseLocation }) { 7 | return 8 | 9 | 10 | } 11 | 12 | export default CloseMessages 13 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # base image 2 | FROM node:8.9.2 3 | 4 | # set working directory 5 | RUN mkdir /usr/src/app 6 | WORKDIR /usr/src/app 7 | 8 | # add `/usr/src/app/node_modules/.bin` to $PATH 9 | ENV PATH /usr/src/app/node_modules/.bin:$PATH 10 | 11 | # install and cache app dependencies 12 | COPY package.json /usr/src/app/package.json 13 | COPY yarn.lock /usr/src/app/yarn.lock 14 | 15 | RUN yarn install 16 | 17 | # start app 18 | CMD ["yarn", "start"] 19 | -------------------------------------------------------------------------------- /scripts/templates/Component.class.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types' 2 | import React, { Component } from 'react' 3 | import './ReplaceComponent.scss' 4 | const { string } = PropTypes 5 | 6 | export default class ReplaceComponent extends Component { 7 | static propTypes = { 8 | example: string 9 | } 10 | 11 | render () { 12 | const { example } = this.props 13 | return
{example}
14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/components/PostCard/PostCompletion/PostCompletion.scss: -------------------------------------------------------------------------------- 1 | .postCompletion { 2 | background-color: #F2F2F2; 3 | color: $color-regent; 4 | font-size: 14px; 5 | display: flex; 6 | align-items: center; 7 | justify-content: space-between; 8 | margin: 8px; 9 | padding: 15px; 10 | background: rgba(213, 236, 250, .3); 11 | border: 1px dashed rgba(213, 236, 250, 1); 12 | border-radius: 5px; 13 | 14 | div { line-height: 29px; } 15 | } 16 | -------------------------------------------------------------------------------- /src/graphql/queries/SubCommentsQuery.graphql: -------------------------------------------------------------------------------- 1 | #import "../fragments/CommentFieldsFragment.graphql" 2 | 3 | query SubCommentsQuery ( 4 | $id: ID, 5 | $cursor: ID 6 | ) { 7 | comment(id: $id) { 8 | id 9 | childComments(first: 10, cursor: $cursor, order: "desc") { 10 | items { 11 | ...CommentFields 12 | post { 13 | id 14 | } 15 | } 16 | total 17 | hasMore 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/routes/Messages/CloseMessages/CloseMessages.scss: -------------------------------------------------------------------------------- 1 | .close-messages { 2 | cursor: pointer; 3 | padding: $space-2x 0; 4 | 5 | &:hover { 6 | text-decoration: none; 7 | 8 | .close-messages-icon { 9 | color: $color-rhino-60; 10 | } 11 | } 12 | } 13 | 14 | @media screen and (max-width: 650px) { 15 | .close-messages { 16 | position: absolute; 17 | left: 7px; 18 | z-index: 5; 19 | top: 22px; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/store/models/PersonConnection.js: -------------------------------------------------------------------------------- 1 | import { attr, fk, Model } from 'redux-orm' 2 | 3 | class PersonConnection extends Model { 4 | toString () { 5 | return `PersonConnection: ${this.type}` 6 | } 7 | } 8 | 9 | export default PersonConnection 10 | 11 | PersonConnection.modelName = 'PersonConnection' 12 | PersonConnection.fields = { 13 | person: fk('Person'), 14 | type: attr(), 15 | createdAt: attr(), 16 | updatedAt: attr() 17 | } 18 | -------------------------------------------------------------------------------- /src/components/Affiliation/__snapshots__/Affiliation.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Affiliation matches last snapshot 1`] = ` 4 |
7 |
10 | Cheesemonger 11 |
12 |
13 | at 14 |
15 |
18 | La Fromagerie 19 |
20 |
21 | `; 22 | -------------------------------------------------------------------------------- /src/store/selectors/isGroupRoute.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect' 2 | import getRouteParam from './getRouteParam' 3 | 4 | const isGroupRoute = createSelector( 5 | getSlugFromLocation, 6 | slug => !!slug 7 | ) 8 | 9 | export default isGroupRoute 10 | 11 | export function getSlugFromLocation (state, props) { 12 | return getRouteParam('detailGroupSlug', props, false) || getRouteParam('groupSlug', props, false) || props.groupSlug 13 | } 14 | -------------------------------------------------------------------------------- /src/graphql/fragments/groupsQueryFragment.js: -------------------------------------------------------------------------------- 1 | import groupFieldsFragment from 'graphql/fragments/groupFieldsFragment' 2 | 3 | const groupsQueryFragment = ` 4 | groups( 5 | boundingBox: $boundingBox, 6 | context: $context, 7 | parentSlugs: $parentSlugs, 8 | search: $search, 9 | sortBy: $sortBy, 10 | visibility: $visibility 11 | ) { 12 | items { 13 | ${groupFieldsFragment(false)} 14 | } 15 | }` 16 | 17 | export default groupsQueryFragment 18 | -------------------------------------------------------------------------------- /src/routes/UserSettings/AccountSettingsTab/AccountSettingsTab.test.js: -------------------------------------------------------------------------------- 1 | import AccountSettingsTab from './AccountSettingsTab' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | describe('AccountSettingsTab', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow( {}} />) 10 | expect(wrapper).toMatchSnapshot() 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | node_modules 5 | 6 | # testing 7 | coverage 8 | 9 | # production 10 | build 11 | build-hc 12 | es5 13 | 14 | # local config 15 | config/ssl 16 | 17 | # misc 18 | .DS_Store 19 | .env 20 | .env.old 21 | .env.production 22 | npm-debug.log 23 | 24 | .floo 25 | .flooignore 26 | 27 | yarn-error.log 28 | .idea 29 | yarn.lock 30 | .yarn 31 | .yarnrc.yml 32 | -------------------------------------------------------------------------------- /src/components/SendAnnouncementModal/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import ReactDOM from 'react-dom' 3 | import SendAnnouncementModal from './SendAnnouncementModal' 4 | import { rootDomId } from 'client/util' 5 | 6 | const SendAnnouncementPortal = function (props) { 7 | return ReactDOM.createPortal( 8 | , 9 | document.getElementById(rootDomId) 10 | ) 11 | } 12 | 13 | export default SendAnnouncementPortal 14 | -------------------------------------------------------------------------------- /src/graphql/queries/MessageThreadMessagesQuery.graphql: -------------------------------------------------------------------------------- 1 | query MessageThreadMessagesQuery ($id: ID, $cursor: ID) { 2 | messageThread (id: $id) { 3 | id 4 | messages(first: 80, cursor: $cursor, order: "desc") { 5 | items { 6 | id 7 | text 8 | createdAt 9 | creator { 10 | id 11 | name 12 | avatarUrl 13 | } 14 | } 15 | total 16 | hasMore 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/graphql/queries/PeopleQuery.graphql: -------------------------------------------------------------------------------- 1 | query PeopleQuery ( 2 | $first: Int, 3 | $autocomplete: String, 4 | $groupIds: [ID], 5 | $offset: Int 6 | ) { 7 | groups(groupIds: $groupIds) { 8 | items { 9 | id 10 | members(first: $first, offset: $offset, search: $autocomplete, sortBy: "name", order: "asc") { 11 | items { 12 | id 13 | name 14 | avatarUrl 15 | } 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/DeleteSettingsTab/DeleteSettingsTab.test.js: -------------------------------------------------------------------------------- 1 | import DeleteSettingsTab from './DeleteSettingsTab' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('renders correctly', () => { 6 | const group = { 7 | id: 1, 8 | name: 'Hylo' 9 | } 10 | 11 | const wrapper = shallow( {}} 14 | />) 15 | expect(wrapper).toMatchSnapshot() 16 | }) 17 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/Signup/VerifyEmail/VerifyEmail.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render, screen } from 'util/testing/reactTestingLibraryExtended' 3 | import VerifyEmail from './VerifyEmail' 4 | 5 | it('renders correctly', async () => { 6 | render( 7 | 8 | ) 9 | 10 | expect(screen.getByText("We've sent a 6 digit code", { exact: false })).toBeInTheDocument() 11 | }) 12 | -------------------------------------------------------------------------------- /src/store/actions/checkIsPostPublic.js: -------------------------------------------------------------------------------- 1 | import gql from 'graphql-tag' 2 | 3 | export default function checkIsPostPublic (postId) { 4 | return { 5 | type: 'IS_POST_PUBLIC', 6 | graphql: { 7 | query: gql` 8 | query CheckIsPostPublic ($id: ID) { 9 | post (id: $id) { 10 | id 11 | } 12 | } 13 | `, 14 | variables: { id: postId } 15 | }, 16 | meta: { extractModel: 'Post' } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/store/presenters/presentCollection.js: -------------------------------------------------------------------------------- 1 | import presentPost from 'store/presenters/presentPost' 2 | 3 | export default function presentCollection (collection) { 4 | if (!collection) return null 5 | 6 | const linkedPosts = collection.linkedPosts.toModelArray() 7 | return { 8 | ...collection.ref, 9 | posts: linkedPosts.length > 0 ? linkedPosts.map(lp => presentPost(lp.post)) : collection.posts.toModelArray().map(p => presentPost(p)) 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/components/NotFound/NotFound.connector.js: -------------------------------------------------------------------------------- 1 | import { goBack, push } from 'connected-react-router' 2 | import { withRouter } from 'react-router-dom' 3 | import { connect } from 'react-redux' 4 | 5 | function mapDispatchToProps (dispatch, props) { 6 | return { 7 | goBack: () => 8 | dispatch(props.history.length > 2 ? goBack() : push('/')) 9 | } 10 | } 11 | 12 | export default component => 13 | withRouter(connect(null, mapDispatchToProps)(component)) 14 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/AddLocation/AddLocation.connector.test.js: -------------------------------------------------------------------------------- 1 | import { mapDispatchToProps } from './AddLocation.connector' 2 | describe('AddLocation', () => { 3 | it('should call updateUserSettings', () => { 4 | const dispatch = jest.fn(x => x) 5 | const props = {} 6 | const name = 'My Name' 7 | const dispatchProps = mapDispatchToProps(dispatch, props) 8 | expect(dispatchProps.updateUserSettings(name)).toMatchSnapshot() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /src/routes/WelcomeWizardRouter/UploadPhoto/UploadPhoto.connector.test.js: -------------------------------------------------------------------------------- 1 | import { mapDispatchToProps } from './UploadPhoto.connector' 2 | describe('Upload Photo', () => { 3 | it('should call updateUserSettings', () => { 4 | const dispatch = jest.fn(x => x) 5 | const props = {} 6 | const name = 'My Name' 7 | const dispatchProps = mapDispatchToProps(dispatch, props) 8 | expect(dispatchProps.updateUserSettings(name)).toMatchSnapshot() 9 | }) 10 | }) 11 | -------------------------------------------------------------------------------- /src/components/Member/Member.connector.test.js: -------------------------------------------------------------------------------- 1 | import { mapDispatchToProps } from './Member.connector' 2 | 3 | describe('mapDispatchToProps', () => { 4 | it('goToPerson is correct for "groups" context', () => { 5 | const dispatch = jest.fn(x => x) 6 | const props = { 7 | context: 'groups' 8 | } 9 | const dispatchProps = mapDispatchToProps(dispatch, props) 10 | expect(dispatchProps.goToPerson(1, 'anything')()).toMatchSnapshot() 11 | }) 12 | }) 13 | -------------------------------------------------------------------------------- /src/components/SkillsToLearnSection/SkillsToLearnSection.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useTranslation } from 'react-i18next' 3 | import SkillsSection from '../SkillsSection/SkillsSection' 4 | 5 | const SkillsToLearnSection = (props) => { 6 | const { t } = useTranslation() 7 | return 8 | } 9 | 10 | export default SkillsToLearnSection 11 | -------------------------------------------------------------------------------- /src/store/models/GroupTopic.js: -------------------------------------------------------------------------------- 1 | import { attr, Model, fk } from 'redux-orm' 2 | 3 | class GroupTopic extends Model { 4 | toString () { 5 | return `GroupTopic: ${this.topic}` 6 | } 7 | } 8 | 9 | export default GroupTopic 10 | 11 | GroupTopic.modelName = 'GroupTopic' 12 | 13 | GroupTopic.fields = { 14 | id: attr(), 15 | topic: fk('Topic', 'groupTopics'), 16 | group: fk('Group', 'groupTopics'), 17 | postsTotal: attr(), 18 | followersTotal: attr() 19 | } 20 | -------------------------------------------------------------------------------- /src/store/models/ModerationAction.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | class ModerationAction extends Model { 4 | toString () { 5 | return `ModerationAction (${this.id}): ${this.title}` 6 | } 7 | } 8 | 9 | export default ModerationAction 10 | 11 | ModerationAction.modelName = 'ModerationAction' 12 | 13 | ModerationAction.fields = { 14 | id: attr(), 15 | groupId: attr(), 16 | postId: attr(), 17 | status: attr(), 18 | text: attr() 19 | } 20 | -------------------------------------------------------------------------------- /src/components/CheckBox/__snapshots__/CheckBox.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`renders correctly 1`] = ` 4 | 20 | `; 21 | -------------------------------------------------------------------------------- /src/components/Switch/Switch.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './Switch.scss' 3 | 4 | export default function Switch ({ 5 | value, 6 | onClick, 7 | className 8 | }) { 9 | return
10 |
11 |
12 |
13 |
14 |
15 | } 16 | -------------------------------------------------------------------------------- /src/server/newrelic.js: -------------------------------------------------------------------------------- 1 | const newrelic = process.env.NEW_RELIC_LICENSE_KEY && process.env.NODE_ENV !== 'test' 2 | ? require('newrelic') 3 | : null 4 | 5 | export function getBrowserSnippet () { 6 | if (!newrelic) return '' 7 | // FIXME: this should be changed to represent the actual page being loaded. 8 | // it's here for now only because it's required for the browser snippet 9 | newrelic.setTransactionName('/') 10 | return newrelic.getBrowserTimingHeader() 11 | } 12 | -------------------------------------------------------------------------------- /src/store/models/Topic.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | export const TOPIC_VISIBILITY = { 4 | 0: 'Hidden', 5 | 1: 'Visible', 6 | 2: 'Pinned' 7 | } 8 | 9 | class Topic extends Model { 10 | toString () { 11 | return `Topic: ${this.name}` 12 | } 13 | } 14 | 15 | export default Topic 16 | 17 | Topic.modelName = 'Topic' 18 | 19 | Topic.fields = { 20 | id: attr(), 21 | name: attr(), 22 | postsTotal: attr(), 23 | followersTotal: attr() 24 | } 25 | -------------------------------------------------------------------------------- /src/store/selectors/getGroupForDetails.js: -------------------------------------------------------------------------------- 1 | import { createSelector as ormCreateSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | import getRouteParam from 'store/selectors/getRouteParam' 4 | 5 | const getGroupForDetail = ormCreateSelector( 6 | orm, 7 | (state, props) => props.slug || getRouteParam('detailGroupSlug', props) || getRouteParam('groupSlug', props), 8 | ({ Group }, slug) => Group.safeGet({ slug }) 9 | ) 10 | 11 | export default getGroupForDetail 12 | -------------------------------------------------------------------------------- /src/components/PostCard/EventDate/EventDate.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Moment from 'moment-timezone' 3 | import './EventDate.scss' 4 | 5 | export default function EventDate ({ startTime }) { 6 | if (!startTime) return null 7 | const startTimeMoment = Moment(startTime) 8 | return
9 | {startTimeMoment.format('MMM')} 10 | {startTimeMoment.format('D')} 11 |
12 | } 13 | -------------------------------------------------------------------------------- /scripts/build-es5.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if ! test -e package.json; then 3 | echo "Run this script from the app's root directory." 4 | exit 1 5 | fi 6 | 7 | export NODE_ENV=production 8 | for dir in src scripts; do 9 | ./node_modules/.bin/babel --config-file ./babel.config.js --env-name server $dir --out-dir es5/$dir 10 | done 11 | 12 | for file in `find src -name "*.scss"`; do 13 | dest=`echo $file | sed 's/^/es5\//'` 14 | mkdir -p `dirname $dest` 15 | cp $file $dest 16 | done 17 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/ImportExportSettingsTab/ImportExportSettingsTab.test.js: -------------------------------------------------------------------------------- 1 | import ImportExportSettingsTab from './ImportExportSettingsTab' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('renders correctly', () => { 6 | const group = { 7 | id: 1, 8 | name: 'Hylo' 9 | } 10 | 11 | const wrapper = shallow( {}} 14 | />) 15 | expect(wrapper).toMatchSnapshot() 16 | }) 17 | -------------------------------------------------------------------------------- /src/store/models/Activity.js: -------------------------------------------------------------------------------- 1 | import { attr, fk, Model } from 'redux-orm' 2 | 3 | class Activity extends Model { 4 | toString () { 5 | return `Message: ${this.id}` 6 | } 7 | } 8 | 9 | export default Activity 10 | 11 | Activity.modelName = 'Activity' 12 | 13 | Activity.fields = { 14 | id: attr(), 15 | actor: fk('Person'), 16 | post: fk('Post'), 17 | comment: fk('Comment'), 18 | group: fk('Group'), 19 | unread: attr(), 20 | action: attr(), 21 | meta: attr() 22 | } 23 | -------------------------------------------------------------------------------- /src/store/models/Comment.js: -------------------------------------------------------------------------------- 1 | import { attr, fk, Model } from 'redux-orm' 2 | 3 | class Comment extends Model { 4 | toString () { 5 | return `Comment: ${this.name}` 6 | } 7 | } 8 | 9 | export default Comment 10 | 11 | Comment.modelName = 'Comment' 12 | 13 | Comment.fields = { 14 | id: attr(), 15 | text: attr(), 16 | creator: fk('Person', 'comments'), 17 | post: fk('Post', 'comments'), 18 | parentComment: fk('Comment', 'childComments'), 19 | createdAt: attr() 20 | } 21 | -------------------------------------------------------------------------------- /src/store/selectors/getLastViewedGroup.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect' 2 | import getMe from './getMe' 3 | 4 | export const getLastViewedGroup = createSelector( 5 | getMe, 6 | currentUser => { 7 | if (currentUser?.memberships.count() > 0) { 8 | return currentUser 9 | .memberships 10 | .orderBy(m => new Date(m.lastViewedAt), 'desc') 11 | .first() 12 | .group 13 | } 14 | } 15 | ) 16 | 17 | export default getLastViewedGroup 18 | -------------------------------------------------------------------------------- /src/components/SettingsControl/SettingsControl.test.js: -------------------------------------------------------------------------------- 1 | import SettingsControl from './SettingsControl' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | describe('SettingsControl', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow() 8 | expect(wrapper.find('label').text()).toEqual('A Control') 9 | expect(wrapper.find('input').prop('value')).toEqual('the value') 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /src/store/actions/deleteComment.js: -------------------------------------------------------------------------------- 1 | import { DELETE_COMMENT } from 'store/constants' 2 | 3 | export default function deleteComment (id) { 4 | return { 5 | type: DELETE_COMMENT, 6 | graphql: { 7 | query: `mutation DeleteComment ($id: ID) { 8 | deleteComment(id: $id) { 9 | success 10 | } 11 | }`, 12 | variables: { 13 | id 14 | } 15 | }, 16 | meta: { 17 | optimistic: true, 18 | id 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/store/actions/deletePost.js: -------------------------------------------------------------------------------- 1 | import { DELETE_POST } from 'store/constants' 2 | 3 | export default function deletePost (id, groupId) { 4 | return { 5 | type: DELETE_POST, 6 | graphql: { 7 | query: `mutation ($id: ID) { 8 | deletePost(id: $id) { 9 | success 10 | } 11 | }`, 12 | variables: { 13 | id 14 | } 15 | }, 16 | meta: { 17 | optimistic: true, 18 | id, 19 | groupId 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/components/PostListRow/PostListRow.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { push } from 'connected-react-router' 3 | import { postUrl } from 'util/navigation' 4 | 5 | export function mapDispatchToProps (dispatch, props) { 6 | const { post, routeParams, querystringParams } = props 7 | 8 | return { 9 | showDetails: () => dispatch(push(postUrl(post.id, routeParams, querystringParams))) 10 | } 11 | } 12 | 13 | export default connect(() => ({}), mapDispatchToProps) 14 | -------------------------------------------------------------------------------- /src/store/actions/checkIsPublicGroup.js: -------------------------------------------------------------------------------- 1 | import gql from 'graphql-tag' 2 | 3 | export default function checkIsPublicGroup (groupSlug) { 4 | return { 5 | type: 'IS_GROUP_PUBLIC', 6 | graphql: { 7 | query: gql` 8 | query CheckIsGroupPublic ($slug: String) { 9 | group (slug: $slug) { 10 | visibility 11 | } 12 | } 13 | `, 14 | variables: { slug: groupSlug } 15 | }, 16 | meta: { extractModel: 'Group' } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/store/actions/sendPasswordReset.js: -------------------------------------------------------------------------------- 1 | import { SEND_PASSWORD_RESET } from 'store/constants' 2 | 3 | export default function sendPasswordReset (email) { 4 | return { 5 | type: SEND_PASSWORD_RESET, 6 | graphql: { 7 | query: ` 8 | mutation SendPasswordReset ($email: String!) { 9 | sendPasswordReset(email: $email) { 10 | success 11 | } 12 | } 13 | `, 14 | variables: { 15 | email 16 | } 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/util/asyncDebounce.js: -------------------------------------------------------------------------------- 1 | import { debounce } from 'lodash/fp' 2 | 3 | // From: https://github.com/lodash/lodash/issues/4815#issuecomment-815866904 4 | export const asyncDebounce = (wait, func) => { 5 | const debounced = debounce(wait, (resolve, reject, args) => { 6 | func(...args).then(resolve).catch(reject) 7 | }) 8 | 9 | return (...args) => 10 | new Promise((resolve, reject) => { 11 | debounced(resolve, reject, args) 12 | }) 13 | } 14 | 15 | export default asyncDebounce 16 | -------------------------------------------------------------------------------- /src/components/PostCard/PeopleInfo/PeopleInfo.scss: -------------------------------------------------------------------------------- 1 | .people-container { 2 | display: flex; 3 | align-items: center; 4 | } 5 | 6 | .people { 7 | margin-right: 4px; 8 | white-space: nowrap; 9 | display: inline-block; 10 | vertical-align: middle; 11 | } 12 | 13 | .caption { 14 | composes: caption-lt-lg from 'css/typography.scss'; 15 | } 16 | 17 | .constrained .caption { 18 | font-size: 10px; 19 | line-height: 12px; 20 | } 21 | 22 | .constrained .people { 23 | margin-right: 5px; 24 | } 25 | -------------------------------------------------------------------------------- /src/routes/Messages/PeopleSelector/PeopleListItem/PeopleListItem.test.js: -------------------------------------------------------------------------------- 1 | import PeopleListItem from './PeopleListItem' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('matches the last snapshot', () => { 6 | const person = { 7 | active: true, 8 | id: '1', 9 | name: 'Wombat', 10 | avatarUrl: 'https://wombat.life' 11 | } 12 | const wrapper = shallow( {}} person={person} />) 13 | expect(wrapper).toMatchSnapshot() 14 | }) 15 | -------------------------------------------------------------------------------- /src/store/reducers/locationHistory.js: -------------------------------------------------------------------------------- 1 | import { LOCATION_CHANGE } from 'connected-react-router' 2 | 3 | const initialState = { 4 | previousLocation: null, 5 | currentLocation: null 6 | } 7 | 8 | export default (state = initialState, action) => { 9 | switch (action.type) { 10 | case LOCATION_CHANGE: 11 | return { 12 | previousLocation: state.currentLocation, 13 | currentLocation: action.payload.location 14 | } 15 | default: 16 | return state 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/store/selectors/getMyGroups.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | import getMyMemberships from 'store/selectors/getMyMemberships' 4 | 5 | export const getMyGroups = createSelector( 6 | orm, 7 | getMyMemberships, 8 | (_, memberships) => { 9 | return memberships 10 | .map(m => ({ ...m.group.ref, newPostCount: m.newPostCount })) 11 | .sort((a, b) => a.name.localeCompare(b.name)) 12 | } 13 | ) 14 | 15 | export default getMyGroups 16 | -------------------------------------------------------------------------------- /src/components/SimpleTabBar/SimpleTabBar.js: -------------------------------------------------------------------------------- 1 | import { capitalize } from 'lodash/fp' 2 | import React from 'react' 3 | 4 | import './SimpleTabBar.scss' 5 | 6 | export default function SimpleTabBar ({ currentTab, tabNames, selectTab }) { 7 | return
    8 | {tabNames.map(name => 9 |
  • selectTab(name)}> 12 | {capitalize(name)} 13 |
  • )} 14 |
15 | } 16 | -------------------------------------------------------------------------------- /src/routes/UserSettings/PaymentSettingsTab/PaymentSettingsTab.test.js: -------------------------------------------------------------------------------- 1 | import PaymentSettingsTab from './PaymentSettingsTab' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | describe('PaymentSettingsTab', () => { 6 | it('renders correctly', () => { 7 | const wrapper = shallow( true }} 9 | updateUserSettings={() => {}} 10 | queryParams={{}} />) 11 | expect(wrapper).toMatchSnapshot() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /src/routes/UserSettings/UserSettings.store.test.js: -------------------------------------------------------------------------------- 1 | import { updateAllMemberships, registerStripeAccount } from './UserSettings.store' 2 | 3 | describe('updateAllMemberships', () => { 4 | it('matches snapshot', () => { 5 | expect(updateAllMemberships([1, 3, 5], { sendEmail: true })).toMatchSnapshot() 6 | }) 7 | }) 8 | 9 | describe('registerStripeAccount', () => { 10 | it('matches snapshot', () => { 11 | expect(registerStripeAccount('anauthorizationcodexyz')).toMatchSnapshot() 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /src/store/actions/fetchPosts.test.js: -------------------------------------------------------------------------------- 1 | import fetchPosts from './fetchPosts' 2 | 3 | it('works for a group', () => { 4 | expect(fetchPosts({ 5 | context: 'groups', 6 | id: 'foo', 7 | offset: 20, 8 | search: 'gardening', 9 | filter: 'offer' 10 | })).toMatchSnapshot() 11 | }) 12 | 13 | it('works for all groups', () => { 14 | expect(fetchPosts({ 15 | context: 'all', 16 | offset: 20, 17 | search: 'graphic design', 18 | filter: 'request' 19 | })).toMatchSnapshot() 20 | }) 21 | -------------------------------------------------------------------------------- /src/components/Switch/__snapshots__/Switch.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Switch renders correctly 1`] = ` 4 |
9 |
12 |
15 |
18 |
21 |
22 | `; 23 | -------------------------------------------------------------------------------- /src/components/GroupButton/__snapshots__/GroupButton.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`GroupButton matches last snapshot 1`] = ` 4 | 20 | `; 21 | -------------------------------------------------------------------------------- /src/graphql/fragments/CommentFieldsFragment.graphql: -------------------------------------------------------------------------------- 1 | fragment CommentFields on Comment { 2 | id 3 | text 4 | creator { 5 | id 6 | name 7 | avatarUrl 8 | } 9 | myReactions { 10 | emojiFull 11 | id 12 | } 13 | commentReactions { 14 | emojiFull 15 | id 16 | user { 17 | id 18 | name 19 | } 20 | } 21 | attachments { 22 | id 23 | position 24 | type 25 | url 26 | } 27 | parentComment { 28 | id 29 | } 30 | createdAt 31 | editedAt 32 | } 33 | -------------------------------------------------------------------------------- /src/routes/AuthLayoutRouter/components/TopNav/NoItems/NoItems.scss: -------------------------------------------------------------------------------- 1 | .no-items { 2 | text-align: center; 3 | height: $messages-body-height; 4 | 5 | h3 { 6 | color: $color-dove-gray-50; 7 | font-size: 25px; 8 | margin-top: 25px; 9 | padding: 10px 30px; 10 | position: absolute; 11 | text-align: center; 12 | width: 100%; 13 | } 14 | .image { 15 | background: no-repeat center; 16 | height: $messages-body-height; 17 | background-size: calc($messages-body-height/2); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/store/selectors/getPost.js: -------------------------------------------------------------------------------- 1 | import { createSelector as ormCreateSelector } from 'redux-orm' 2 | import orm from 'store/models' 3 | import getRouteParam from 'store/selectors/getRouteParam' 4 | import getQuerystringParam from 'store/selectors/getQuerystringParam' 5 | 6 | const getPost = ormCreateSelector( 7 | orm, 8 | (state, props) => getRouteParam('postId', props) || getQuerystringParam('fromPostId', props), 9 | ({ Post }, id) => { 10 | return Post.withId(id) 11 | } 12 | ) 13 | 14 | export default getPost 15 | -------------------------------------------------------------------------------- /src/components/Tooltip/Tooltip.scss: -------------------------------------------------------------------------------- 1 | .tooltip { 2 | font-size: 12px; 3 | padding: 5px 12px; 4 | border-radius: 24px !important; 5 | font-weight: bold; 6 | // @see Tooltip.js - styles are applied as props 7 | // background: $color-white !important; 8 | // color: $color-member !important; 9 | // border: 1px solid $color-picton-blue !important; 10 | box-shadow: $box-shadow-tooltip; 11 | } 12 | 13 | 14 | @media screen and (max-width: 500px) { 15 | .tooltip { 16 | display: none !important; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/components/TopicSupportComingSoon/TopicSupportComingSoon.scss: -------------------------------------------------------------------------------- 1 | .container { 2 | margin-top: 50px; 3 | text-align: center; 4 | } 5 | 6 | .back-button { 7 | text-align: center; 8 | cursor: pointer; 9 | background-color: $color-caribbean-green; 10 | } 11 | 12 | .axolotl-digging-image { 13 | width: 300px; 14 | height: 300px; 15 | display: block; 16 | margin: 0 auto; 17 | } 18 | 19 | .gray-text { 20 | color: $color-rhino-60; 21 | margin-bottom: 30px; 22 | font-size: 80%; 23 | line-height: 180%; 24 | } 25 | -------------------------------------------------------------------------------- /src/routes/Messages/PeopleSelector/MatchingPeopleListItem/__snapshots__/MatchingPeopleListItem.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`matches last snapshot 1`] = ` 4 |
7 | 11 | 14 | 15 | 19 | 20 |
21 | `; 22 | -------------------------------------------------------------------------------- /src/store/actions/fetchForCurrentUser.js: -------------------------------------------------------------------------------- 1 | import { get } from 'lodash/fp' 2 | import { FETCH_FOR_CURRENT_USER } from 'store/constants' 3 | import MeQuery from 'graphql/queries/MeQuery' 4 | 5 | export default function fetchForCurrentUser () { 6 | return { 7 | type: FETCH_FOR_CURRENT_USER, 8 | graphql: { 9 | query: MeQuery 10 | }, 11 | meta: { 12 | extractModel: [ 13 | { 14 | getRoot: get('me'), 15 | modelName: 'Me' 16 | } 17 | ] 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/components/CommentCard/CommentCard.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { push } from 'connected-react-router' 3 | import { postUrl } from 'util/navigation' 4 | 5 | export function mapStateToProps (state, props) { 6 | return { } 7 | } 8 | 9 | export function mapDispatchToProps (dispatch, props) { 10 | return { 11 | showDetails: () => 12 | dispatch(push(postUrl(props.comment.post.id, props.routeParams))) 13 | } 14 | } 15 | 16 | export default connect(mapStateToProps, mapDispatchToProps) 17 | -------------------------------------------------------------------------------- /src/routes/GroupSettings/InviteSettingsTab/InviteSettingsTab.test.js: -------------------------------------------------------------------------------- 1 | import InviteSettingsTab from './InviteSettingsTab' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | it('renders correctly', () => { 6 | const group = { 7 | id: 1, 8 | name: 'Hylo' 9 | } 10 | 11 | const wrapper = shallow( {}} 14 | inviteLink='http://www.hylo.com/c/hylo/join/lalala' 15 | />) 16 | expect(wrapper).toMatchSnapshot() 17 | }) 18 | -------------------------------------------------------------------------------- /scripts/templates/Component.connectorWithStore.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { 3 | fetchExample, 4 | getExample 5 | } from './Component.store' 6 | // import getMe from 'store/selectors/getMe' 7 | 8 | export function mapStateToProps (state, props) { 9 | return { 10 | example: getExample(state, props) 11 | // currentUser: getMe(state, props) 12 | } 13 | } 14 | 15 | export const mapDispatchToProps = { 16 | fetchExample 17 | } 18 | 19 | export default connect(mapStateToProps, mapDispatchToProps) 20 | -------------------------------------------------------------------------------- /src/components/BadgedIcon/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import Icon from '../Icon' 3 | import cx from 'classnames' 4 | import './component.scss' 5 | 6 | export default function BadgedIcon (props) { 7 | const { className, showBadge, green, ...rest } = props 8 | const styleNames = cx({ green }, showBadge ? 'badge' : 'badge-hidden') 9 | return ( 10 | 11 | 12 | 13 | ) 14 | } 15 | -------------------------------------------------------------------------------- /src/routes/OAuth/Consent/Consent.store.js: -------------------------------------------------------------------------------- 1 | export const OAUTH_CONFIRM = 'OAuth/CONSENT_CONFIRM' 2 | export const OAUTH_CANCEL = 'OAuth/CANCEL' 3 | 4 | export function confirm (uid) { 5 | return { 6 | type: OAUTH_CONFIRM, 7 | payload: { 8 | api: { method: 'post', path: `/noo/oidc/${uid}/confirm` } 9 | } 10 | } 11 | } 12 | 13 | export function cancel (uid) { 14 | return { 15 | type: OAUTH_CANCEL, 16 | payload: { 17 | api: { method: 'post', path: `/noo/oidc/${uid}/abort` } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/store/actions/fetchPeople.test.js: -------------------------------------------------------------------------------- 1 | import fetchPeople from 'store/actions/fetchPeople' 2 | 3 | it('matches the last snapshot', () => { 4 | const graphql = { 5 | query: 'All the lonely people / Where do they all come from?', 6 | variables: { 7 | autocomplete: 'Tchaikovs', 8 | first: 100 9 | } 10 | } 11 | const { query, variables } = graphql 12 | const actual = fetchPeople({ autocomplete: variables.autocomplete, groupIds: [], first: variables.first, query }) 13 | expect(actual).toMatchSnapshot() 14 | }) 15 | -------------------------------------------------------------------------------- /src/store/middleware/userBlockingMiddleware.js: -------------------------------------------------------------------------------- 1 | import { BLOCK_USER, UNBLOCK_USER } from '../constants' 2 | import fetchForCurrentUser from 'store/actions/fetchForCurrentUser' 3 | import resetStore from '../actions/resetStore' 4 | 5 | export default function userBlockingMiddleware (store) { 6 | return next => action => { 7 | if (action.type === BLOCK_USER || action.type === UNBLOCK_USER) { 8 | store.dispatch(resetStore()) 9 | store.dispatch(fetchForCurrentUser()) 10 | } 11 | return next(action) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/store/models/Invitation.js: -------------------------------------------------------------------------------- 1 | import { attr, fk, Model } from 'redux-orm' 2 | 3 | class Invitation extends Model { 4 | toString () { 5 | return `Invitation: ${this.id}` 6 | } 7 | } 8 | 9 | export default Invitation 10 | 11 | Invitation.modelName = 'Invitation' 12 | Invitation.fields = { 13 | id: attr(), 14 | email: attr(), 15 | createdAt: attr(), 16 | creator: fk('Person', 'createdInvites'), 17 | group: fk('Group', 'pendingInvitations'), 18 | lastSentAt: attr(), 19 | resent: attr(), 20 | token: attr() 21 | } 22 | -------------------------------------------------------------------------------- /src/components/Badge/component.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import './component.scss' 3 | import cx from 'classnames' 4 | 5 | export default function Badge ({ number, expanded, className, border, onClick }) { 6 | if (!number) return null 7 | return 8 | 9 | {number} 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/components/RemovableListItem/RemovableListItem.scss: -------------------------------------------------------------------------------- 1 | .item { 2 | display: flex; 3 | align-items: center; 4 | min-height: 52px; 5 | border-bottom: 1px solid $color-ghost; 6 | } 7 | 8 | .avatar { 9 | margin-right: $space-4x; 10 | } 11 | 12 | .name { 13 | composes: bdy-drk-sm from 'css/typography.scss'; 14 | font-size: 16px; 15 | &:hover { 16 | color: $color-rhino; 17 | text-decoration: none; 18 | } 19 | } 20 | 21 | .remove-button { 22 | margin-left: auto; 23 | composes: text-button from 'css/typography.scss' 24 | } 25 | -------------------------------------------------------------------------------- /src/store/actions/fetchPlatformAgreements.js: -------------------------------------------------------------------------------- 1 | export const FETCH_PLATFORM_AGREEMENTS = 'FETCH_PLATFORM_AGREEMENTS' 2 | 3 | export default function fetchPlatformAgreements () { 4 | return { 5 | type: FETCH_PLATFORM_AGREEMENTS, 6 | graphql: { 7 | query: `query FetchPlatformAgreements { 8 | platformAgreements { 9 | id 10 | text 11 | type 12 | } 13 | }`, 14 | variables: { } 15 | }, 16 | meta: { 17 | extractModel: 'PlatformAgreement' 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/store/models/Attachment.js: -------------------------------------------------------------------------------- 1 | import { attr, fk, Model } from 'redux-orm' 2 | 3 | class Attachment extends Model { 4 | toString () { 5 | return `Attachment (${this.type}): ${this.name}` 6 | } 7 | } 8 | 9 | export default Attachment 10 | 11 | Attachment.modelName = 'Attachment' 12 | 13 | Attachment.fields = { 14 | id: attr(), 15 | type: attr(), 16 | position: attr(), 17 | url: attr(), 18 | thumbnailUrl: attr(), 19 | post: fk('Post', 'attachments'), 20 | comment: fk('Comment', 'attachments'), 21 | createdAt: attr() 22 | } 23 | -------------------------------------------------------------------------------- /src/store/models/SearchResult.js: -------------------------------------------------------------------------------- 1 | import { attr, Model } from 'redux-orm' 2 | 3 | class SearchResult extends Model { 4 | toString () { 5 | return `SearchResult: ${this.id}` 6 | } 7 | 8 | getContent (session) { 9 | const [ type, id ] = this.content.split('-') 10 | return session[type].withId(id) 11 | } 12 | } 13 | 14 | export default SearchResult 15 | 16 | SearchResult.modelName = 'SearchResult' 17 | SearchResult.fields = { 18 | id: attr(), 19 | // this is a polymorphicId, see getContent above 20 | content: attr() 21 | } 22 | -------------------------------------------------------------------------------- /src/components/Widget/MapWidget/MapWidget.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types' 2 | import React, { Component } from 'react' 3 | import { withTranslation } from 'react-i18next' 4 | 5 | import './MapWidget.scss' 6 | 7 | const { array } = PropTypes 8 | 9 | class MapWidget extends Component { 10 | static propTypes = { 11 | map: array 12 | } 13 | 14 | render () { 15 | return ( 16 |
17 | {this.props.t('Community map')} 18 |
19 | ) 20 | } 21 | } 22 | 23 | export default withTranslation()(MapWidget) 24 | -------------------------------------------------------------------------------- /src/routes/Messages/PeopleSelector/PeopleListItem/__snapshots__/PeopleListItem.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`matches the last snapshot 1`] = ` 4 |
  • 7 | 12 |
    13 | 16 | Wombat 17 | 18 | 21 |
    22 |
  • 23 | `; 24 | -------------------------------------------------------------------------------- /src/store/selectors/getChildComments.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect' 2 | import { get } from 'lodash/fp' 3 | import { FETCH_CHILD_COMMENTS } from 'store/constants' 4 | import { makeGetQueryResults } from 'store/reducers/queryResults' 5 | 6 | const getCommentResults = makeGetQueryResults(FETCH_CHILD_COMMENTS) 7 | 8 | export const getHasMoreChildComments = createSelector( 9 | getCommentResults, 10 | get('hasMore') 11 | ) 12 | 13 | export const getTotalChildComments = createSelector( 14 | getCommentResults, 15 | get('total') 16 | ) 17 | -------------------------------------------------------------------------------- /src/store/selectors/getMyGroupMembership.js: -------------------------------------------------------------------------------- 1 | import { createSelector } from 'reselect' 2 | import getMyMemberships from 'store/selectors/getMyMemberships' 3 | import getGroupForCurrentRoute from './getGroupForCurrentRoute' 4 | 5 | export const getMyGroupMembership = createSelector( 6 | getGroupForCurrentRoute, 7 | getMyMemberships, 8 | (group, memberships) => { 9 | if (group && memberships.length > 0) { 10 | return memberships.find(m => m.group.id === group.id) 11 | } 12 | } 13 | ) 14 | 15 | export default getMyGroupMembership 16 | -------------------------------------------------------------------------------- /src/components/PostCard/EventDate/EventDate.scss: -------------------------------------------------------------------------------- 1 | .eventDate { 2 | border-radius: 4px; 3 | background-color: rgba(254, 72, 80, 1); 4 | width: 45px; 5 | height: 45px; 6 | display: flex; 7 | flex-direction: column; 8 | align-items: center; 9 | padding: 8px; 10 | } 11 | 12 | .month { 13 | text-transform: uppercase; 14 | color: white; 15 | font-size: 12px !important; 16 | line-height: 0.6; 17 | font-size: 20px; 18 | } 19 | 20 | .day { 21 | color: white; 22 | font-size: 24px; 23 | line-height: 24px; 24 | color: white; 25 | } 26 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberPosts/MemberPosts.test.js: -------------------------------------------------------------------------------- 1 | import { shallow } from 'enzyme' 2 | import React from 'react' 3 | 4 | import MemberPosts from './MemberPosts' 5 | import denormalized from '../MemberProfile.test.json' 6 | 7 | describe.only('MemberPosts', () => { 8 | const { person } = denormalized.data 9 | 10 | it('renders the same as the last snapshot', () => { 11 | const wrapper = shallow( 12 | 13 | ) 14 | expect(wrapper).toMatchSnapshot() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /src/store/actions/removePost.js: -------------------------------------------------------------------------------- 1 | import { REMOVE_POST } from 'store/constants' 2 | 3 | export default function removePost (postId, slug) { 4 | return { 5 | type: REMOVE_POST, 6 | graphql: { 7 | query: `mutation ($postId: ID, $slug: String) { 8 | removePost(postId: $postId, slug: $slug) { 9 | success 10 | } 11 | }`, 12 | variables: { 13 | postId, 14 | slug 15 | } 16 | }, 17 | meta: { 18 | optimistic: true, 19 | postId, 20 | slug 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/routes/AllTopics/__snapshots__/AllTopics.store.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`deleteGroupTopic should match latest snapshot 1`] = ` 4 | Object { 5 | "graphql": Object { 6 | "query": "mutation ($id: ID) { 7 | deleteGroupTopic(id: $id) { 8 | success 9 | } 10 | }", 11 | "variables": Object { 12 | "id": 135, 13 | }, 14 | }, 15 | "meta": Object { 16 | "id": 135, 17 | "optimistic": true, 18 | }, 19 | "type": "AllTopics/DELETE_GROUP_TOPIC", 20 | } 21 | `; 22 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/ManageNotifications/ManageNotifications.scss: -------------------------------------------------------------------------------- 1 | .wrapper { 2 | padding: 30px; 3 | } 4 | 5 | .setting-explanation { 6 | composes: caption-lt-lg from 'css/typography.scss'; 7 | font-size: 13px; 8 | color: black; 9 | margin-bottom: 0; 10 | } 11 | 12 | .form-wrapper { 13 | padding: 0px; 14 | } 15 | 16 | .setting-wrapper { 17 | padding-bottom: 0px; 18 | } 19 | 20 | .unsubscribeAllLabel { 21 | color: #2C4059; 22 | } 23 | 24 | .submit { 25 | composes: submit from '../Login/Login.scss'; 26 | margin-top: 20px; 27 | } 28 | -------------------------------------------------------------------------------- /src/store/presenters/presentGroupRelationshipInvite.js: -------------------------------------------------------------------------------- 1 | export default function presentGroupRelationshipInvite (invite) { 2 | if (!invite) return null 3 | return { 4 | ...invite.ref, 5 | fromGroup: invite.fromGroup ? invite.fromGroup.ref : null, 6 | questionAnswers: invite.questionAnswers ? invite.questionAnswers.toModelArray().map(qa => { 7 | return { 8 | ...qa.ref, 9 | question: qa.question ? qa.question.ref : null 10 | } 11 | }) : [], 12 | toGroup: invite.toGroup ? invite.toGroup.ref : null 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/graphql/fragments/groupTopicsQueryFragment.js: -------------------------------------------------------------------------------- 1 | export default 2 | `groupTopics( 3 | first: $first, 4 | offset: $offset, 5 | sortBy: $sortBy, 6 | order: $order, 7 | subscribed: $subscribed, 8 | autocomplete: $autocomplete 9 | ) { 10 | hasMore 11 | total 12 | items { 13 | id 14 | followersTotal 15 | isDefault 16 | isSubscribed 17 | lastReadPostId 18 | newPostCount 19 | postsTotal 20 | visibility 21 | group { 22 | id 23 | } 24 | topic { 25 | id 26 | name 27 | } 28 | } 29 | } 30 | ` 31 | -------------------------------------------------------------------------------- /src/store/actions/blockUser.js: -------------------------------------------------------------------------------- 1 | import { AnalyticsEvents } from 'hylo-shared' 2 | import { BLOCK_USER } from '../constants' 3 | 4 | export default function blockUser (blockedUserId) { 5 | return { 6 | type: BLOCK_USER, 7 | graphql: { 8 | query: `mutation ($blockedUserId: ID) { 9 | blockUser (blockedUserId: $blockedUserId) { 10 | success 11 | } 12 | }`, 13 | variables: { 14 | blockedUserId 15 | } 16 | }, 17 | meta: { 18 | analytics: AnalyticsEvents.BLOCK_USER 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/store/actions/fetchTopic.js: -------------------------------------------------------------------------------- 1 | import { FETCH_TOPIC } from 'store/constants' 2 | 3 | export default function fetchTopic (name, id) { 4 | return { 5 | type: FETCH_TOPIC, 6 | graphql: { 7 | query: `query ($name: String, $id: ID) { 8 | topic(name: $name, id: $id) { 9 | id 10 | name 11 | postsTotal 12 | followersTotal 13 | } 14 | }`, 15 | variables: { 16 | name, 17 | id 18 | } 19 | }, 20 | meta: { 21 | extractModel: 'Topic' 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/store/reducers/pending.js: -------------------------------------------------------------------------------- 1 | export const initialState = {} 2 | 3 | export default function pending (state = initialState, action) { 4 | const { type, meta, error } = action 5 | 6 | if (error) return state 7 | 8 | const originalType = type.replace(/_PENDING/, '') 9 | 10 | if (type.endsWith('_PENDING')) { 11 | return { 12 | ...state, 13 | [originalType]: meta || true 14 | } 15 | } else if (state[originalType]) { 16 | return { 17 | ...state, 18 | [originalType]: null 19 | } 20 | } 21 | 22 | return state 23 | } 24 | -------------------------------------------------------------------------------- /src/components/NoPosts/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { useTranslation } from 'react-i18next' 3 | import './NoPosts.scss' 4 | 5 | import { jollyAxolotl } from 'util/assets' 6 | 7 | const NoPosts = ({ message, className }) => { 8 | const { t } = useTranslation() 9 | const tMessage = message || t('Nothing to see here') 10 | return ( 11 |
    12 | 13 |
    14 |

    {tMessage}

    15 |
    16 | ) 17 | } 18 | 19 | export default NoPosts 20 | -------------------------------------------------------------------------------- /src/components/CreateGroup/CreateGroup.test.js: -------------------------------------------------------------------------------- 1 | import CreateGroup from './CreateGroup' 2 | import { shallow } from 'enzyme' 3 | import React from 'react' 4 | 5 | describe('CreateGroup', () => { 6 | it('matches snapshot', () => { 7 | const wrapper = shallow() 8 | expect(wrapper).toMatchSnapshot() 9 | }) 10 | 11 | it('Allows for passing in initial name and slug via query parameters', () => { 12 | const wrapper = shallow() 13 | expect(wrapper).toMatchSnapshot() 14 | }) 15 | }) 16 | -------------------------------------------------------------------------------- /src/graphql/queries/MessageThreadQuery.graphql: -------------------------------------------------------------------------------- 1 | query MessageThreadQuery ($id: ID) { 2 | messageThread (id: $id) { 3 | id 4 | unreadCount 5 | lastReadAt 6 | createdAt 7 | updatedAt 8 | participants { 9 | id 10 | name 11 | avatarUrl 12 | } 13 | messages(first: 80, order: "desc") { 14 | items { 15 | id 16 | text 17 | creator { 18 | id 19 | name 20 | avatarUrl 21 | } 22 | createdAt 23 | } 24 | total 25 | hasMore 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberPosts/MemberPosts.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { 3 | getMemberPosts, 4 | fetchMemberPosts 5 | } from './MemberPosts.store' 6 | 7 | export function mapStateToProps (state, props) { 8 | return { 9 | posts: getMemberPosts(state, props) 10 | } 11 | } 12 | 13 | export function mapDispatchToProps (dispatch, props) { 14 | return { 15 | fetchMemberPosts: () => dispatch(fetchMemberPosts(props.routeParams.personId)) 16 | } 17 | } 18 | 19 | export default connect(mapStateToProps, mapDispatchToProps) 20 | -------------------------------------------------------------------------------- /src/store/actions/unBlockUser.js: -------------------------------------------------------------------------------- 1 | import { AnalyticsEvents } from 'hylo-shared' 2 | import { UNBLOCK_USER } from '../constants' 3 | 4 | export default function unBlockUser (blockedUserId) { 5 | return { 6 | type: UNBLOCK_USER, 7 | graphql: { 8 | query: `mutation ($blockedUserId: ID) { 9 | unblockUser (blockedUserId: $blockedUserId) { 10 | success 11 | } 12 | }`, 13 | variables: { 14 | blockedUserId 15 | } 16 | }, 17 | meta: { 18 | analytics: AnalyticsEvents.UNBLOCK_USER 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberComments/MemberComments.test.js: -------------------------------------------------------------------------------- 1 | import { shallow } from 'enzyme' 2 | import React from 'react' 3 | 4 | import MemberComments from './MemberComments' 5 | import denormalized from '../MemberProfile.test.json' 6 | 7 | describe.only('MemberComments', () => { 8 | const { person } = denormalized.data 9 | 10 | it('renders the same as the last snapshot', () => { 11 | const wrapper = shallow( 12 | 13 | ) 14 | expect(wrapper).toMatchSnapshot() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /src/store/actions/fetchMySkills.js: -------------------------------------------------------------------------------- 1 | export const FETCH_MY_SKILLS = `FETCH_MY_SKILLS` 2 | 3 | export default function fetchMySkills (type, limit = 20) { 4 | return { 5 | type: FETCH_MY_SKILLS, 6 | graphql: { 7 | query: `query ($limit: Int) { 8 | me { 9 | id 10 | skills (first: $limit) { 11 | items { 12 | id 13 | name 14 | } 15 | } 16 | } 17 | }`, 18 | variables: { limit } 19 | }, 20 | meta: { 21 | extractModel: 'Me' 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/util/geo.js: -------------------------------------------------------------------------------- 1 | import WebMercatorViewport from '@math.gl/web-mercator' 2 | 3 | export function locationObjectToViewport (priorViewport, locationObject) { 4 | const bbox = locationObject.bbox 5 | if (bbox) { 6 | const bounds = [[parseFloat(bbox[0].lng), parseFloat(bbox[0].lat)], [parseFloat(bbox[1].lng), parseFloat(bbox[1].lat)]] 7 | return new WebMercatorViewport(priorViewport).fitBounds(bounds) 8 | } else { 9 | return { ...priorViewport, longitude: parseFloat(locationObject.center.lng), latitude: parseFloat(locationObject.center.lat), zoom: 12 } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/routes/UserSettings/__snapshots__/UserSettings.connector.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`mapStateToProps returns the right keys 1`] = ` 4 | Object { 5 | "allGroupsSettings": Object { 6 | "sendEmail": true, 7 | "sendPushNotifications": true, 8 | }, 9 | "blockedUsers": Array [], 10 | "confirm": undefined, 11 | "currentUser": undefined, 12 | "fetchPending": undefined, 13 | "memberships": Array [], 14 | "messageSettings": undefined, 15 | "queryParams": Object { 16 | "registered": undefined, 17 | }, 18 | } 19 | `; 20 | -------------------------------------------------------------------------------- /src/components/SimpleTabBar/SimpleTabBar.scss: -------------------------------------------------------------------------------- 1 | .tab-bar { 2 | display: flex; 3 | flex-direction: row; 4 | justify-content: flex-start; 5 | padding: 0; 6 | } 7 | 8 | .tab { 9 | composes: caption-lt-lg from 'css/typography.scss'; 10 | padding: 0 $space-4x; 11 | height: $space-7x; 12 | line-height: $space-7x; 13 | list-style: none; 14 | cursor: pointer; 15 | } 16 | 17 | .tab-active { 18 | composes: tab; 19 | @include font-bold; 20 | color: $color-rhino; 21 | font-size: $space-4x; 22 | background-color: $color-cape-cod-05; 23 | border-radius: $space-1x; 24 | } 25 | -------------------------------------------------------------------------------- /src/store/actions/fetchPerson.test.js: -------------------------------------------------------------------------------- 1 | import fetchPerson from './fetchPerson' 2 | 3 | describe('fetchPerson', () => { 4 | it('returns the correct action', () => { 5 | const expected = { 6 | type: 'FETCH_PERSON', 7 | graphql: { 8 | query: 'A very wombaty query.', 9 | variables: { 10 | id: '12345' 11 | } 12 | }, 13 | meta: { extractModel: 'Person' } 14 | } 15 | const { query, variables } = expected.graphql 16 | const actual = fetchPerson(variables.id, query) 17 | expect(actual).toEqual(expected) 18 | }) 19 | }) 20 | -------------------------------------------------------------------------------- /src/css/bootstrap.scss: -------------------------------------------------------------------------------- 1 | // Core CSS 2 | // @import "node_modules/bootstrap/scss/type"; 3 | @import "node_modules/bootstrap/scss/images"; 4 | // @import "node_modules/bootstrap/scss/code"; 5 | // @import "node_modules/bootstrap/scss/grid"; 6 | // @import "node_modules/bootstrap/scss/tables"; 7 | // @import "node_modules/bootstrap/scss/forms"; 8 | // @import "node_modules/bootstrap/scss/buttons"; 9 | 10 | // Components 11 | // @import "node_modules/bootstrap/scss/card"; 12 | 13 | // Utility classes 14 | @import "node_modules/bootstrap/scss/utilities"; 15 | @import "node_modules/bootstrap/scss/nav"; 16 | -------------------------------------------------------------------------------- /src/routes/NonAuthLayoutRouter/NonAuthLayoutRouter.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { render, screen } from 'util/testing/reactTestingLibraryExtended' 3 | import NonAuthLayoutRouter from './NonAuthLayoutRouter' 4 | 5 | // Currently the test below is going to default route to `/login` 6 | // so until more tests are added this test is identical to the `Login` 7 | // component test 8 | 9 | it('renders correctly', () => { 10 | render( 11 | 12 | ) 13 | 14 | expect(screen.getByText('Sign in to Hylo')).toBeInTheDocument() 15 | }) 16 | -------------------------------------------------------------------------------- /src/store/selectors/getTopicForCurrentRoute.js: -------------------------------------------------------------------------------- 1 | import orm from 'store/models' 2 | import { createSelector as ormCreateSelector } from 'redux-orm' 3 | import getRouteParam from './getRouteParam' 4 | import presentTopic from 'store/presenters/presentTopic' 5 | 6 | const getTopicForCurrentRoute = ormCreateSelector( 7 | orm, 8 | (state, props) => getRouteParam('topicName', props), 9 | (session, topicName) => { 10 | const topic = session.Topic.safeGet({ name: topicName }) 11 | return topic ? presentTopic(topic, {}) : null 12 | } 13 | ) 14 | 15 | export default getTopicForCurrentRoute 16 | -------------------------------------------------------------------------------- /src/components/LocationInput/LocationInput.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { 3 | fetchLocation, 4 | pollingFetchLocation 5 | } from './LocationInput.store.js' 6 | 7 | export function mapStateToProps (state, props) { 8 | return {} 9 | } 10 | 11 | export const mapDispatchToProps = (dispatch, props) => { 12 | return { 13 | fetchLocation, 14 | pollingFetchLocation: (locationData, callback) => pollingFetchLocation(dispatch, locationData, callback) 15 | } 16 | } 17 | 18 | export default connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true }) 19 | -------------------------------------------------------------------------------- /src/components/SkillLabel/component.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types' 2 | import React from 'react' 3 | import cx from 'classnames' 4 | import './component.scss' 5 | 6 | const { string, bool } = PropTypes 7 | 8 | export default function SkillLabel ({ children, label, color = 'dark', active, className }) { 9 | let styleName = cx('label', color, { active }) 10 | return
    11 | {label || children} 12 |
    13 | } 14 | SkillLabel.propTypes = { 15 | label: string, 16 | color: string, 17 | active: bool, 18 | className: string 19 | } 20 | -------------------------------------------------------------------------------- /src/components/TextInput/__snapshots__/TextInput.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`TextInput renders correctly 1`] = ` 4 |
    7 | 16 |
    20 | 23 |
    24 |
    25 | `; 26 | -------------------------------------------------------------------------------- /src/routes/Events/Events.store.js: -------------------------------------------------------------------------------- 1 | export const MODULE_NAME = 'Events' 2 | export const UPDATE_TIMEFRAME = `${MODULE_NAME}/UPDATE_TIMEFRAME` 3 | 4 | export function updateTimeframe (timeframe) { 5 | return { 6 | type: UPDATE_TIMEFRAME, 7 | payload: timeframe 8 | } 9 | } 10 | 11 | // reducer 12 | const DEFAULT_STATE = { 13 | timeframe: 'future' 14 | } 15 | 16 | export default function (state = DEFAULT_STATE, action) { 17 | if (action.type === UPDATE_TIMEFRAME) { 18 | return { 19 | ...state, 20 | timeframe: action.payload 21 | } 22 | } 23 | return state 24 | } 25 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberComments/MemberComments.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | import { 3 | getMemberComments, 4 | fetchMemberComments 5 | } from './MemberComments.store' 6 | 7 | export function mapStateToProps (state, props) { 8 | return { 9 | comments: getMemberComments(state, props) 10 | } 11 | } 12 | 13 | export function mapDispatchToProps (dispatch, props) { 14 | return { 15 | fetchMemberComments: () => dispatch(fetchMemberComments(props.routeParams.personId)) 16 | } 17 | } 18 | 19 | export default connect(mapStateToProps, mapDispatchToProps) 20 | -------------------------------------------------------------------------------- /src/routes/MemberProfile/MemberVotes/MemberVotes.test.js: -------------------------------------------------------------------------------- 1 | import { shallow } from 'enzyme' 2 | import React from 'react' 3 | 4 | import MemberVotes from './MemberVotes' 5 | import denormalized from '../MemberProfile.test.json' 6 | 7 | describe.only('MemberVotes', () => { // TODO REACTIONS: switch this to reactions 8 | const { person } = denormalized.data 9 | 10 | it('renders the same as the last snapshot', () => { 11 | const wrapper = shallow( 12 | 13 | ) 14 | expect(wrapper).toMatchSnapshot() 15 | }) 16 | }) 17 | -------------------------------------------------------------------------------- /src/components/GroupButton/GroupButton.js: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import { groupUrl } from 'util/navigation' 3 | import { DEFAULT_AVATAR } from 'store/models/Group' 4 | import { Link } from 'react-router-dom' 5 | import Button from 'components/Button' 6 | import RoundImage from 'components/RoundImage' 7 | import './GroupButton.scss' 8 | 9 | export default ({ group }) => ( 10 | 15 | ) 16 | -------------------------------------------------------------------------------- /src/components/GroupsList/GroupsList.scss: -------------------------------------------------------------------------------- 1 | .groupRow { 2 | display: flex; 3 | flex-grow: 1; 4 | flex-direction: column; 5 | margin-bottom: 5px; 6 | padding-left: 8px; 7 | } 8 | 9 | .groupCell { 10 | flex: 1; 11 | &:hover { 12 | text-decoration: none; 13 | } 14 | } 15 | 16 | .groupCellName { 17 | composes: text-button from 'css/typography.scss'; 18 | font-size: 15px; 19 | vertical-align: middle; 20 | } 21 | 22 | .groupCellAvatar { 23 | @include image(20px); 24 | display: inline-block; 25 | vertical-align: middle; 26 | border-radius: 4px; 27 | margin-right: 10px; 28 | } 29 | -------------------------------------------------------------------------------- /src/components/PostCard/PostGroups/PostGroups.connector.js: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux' 2 | 3 | export function mapStateToProps (state, props) { 4 | let isPublic = props.isPublic 5 | let groupsPlusPublic = props.groups 6 | 7 | if (isPublic) { 8 | groupsPlusPublic.unshift({ name: 'Public', id: 'public', avatarUrl: '/public-icon.svg', slug: 'public' }) 9 | } 10 | 11 | return { 12 | groups: groupsPlusPublic 13 | } 14 | } 15 | 16 | export function mapDispatchToProps (dispatch, props) { 17 | return {} 18 | } 19 | 20 | export default connect(mapStateToProps, mapDispatchToProps) 21 | --------------------------------------------------------------------------------