├── .babelrc ├── .dockerignore ├── .flowconfig ├── .github └── FUNDING.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .prettierignore ├── .prettierrc.json ├── .python-version ├── CONTRIBUTING.md ├── Dockerfile ├── LICENSE ├── Procfile ├── README.md ├── app.json ├── civic.json ├── civictechprojects ├── __init__.py ├── admin.py ├── apps.py ├── caching │ ├── __init__.py │ └── cache.py ├── forms.py ├── helpers │ ├── __init__.py │ ├── context_preload.py │ ├── projects │ │ └── annotations.py │ └── search │ │ ├── common.py │ │ ├── groups.py │ │ └── projects.py ├── management │ └── commands │ │ ├── data_migration.py │ │ ├── init_testimonials.py │ │ ├── testimonials.json │ │ └── updatecache.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20171119_2223.py │ ├── 0003_auto_20171125_2144.py │ ├── 0004_auto_20171221_0105.py │ ├── 0005_auto_20180104_0438.py │ ├── 0006_auto_20180122_2215.py │ ├── 0007_auto_20180317_1723.py │ ├── 0008_auto_20180317_2315.py │ ├── 0009_auto_20180403_1604.py │ ├── 0010_auto_20180522_1923.py │ ├── 0011_auto_20180529_0426.py │ ├── 0012_auto_20180626_1535.py │ ├── 0013_useralert.py │ ├── 0014_auto_20180806_1942.py │ ├── 0015_project_project_date_modified.py │ ├── 0016_auto_20180911_1618.py │ ├── 0017_auto_20181030_0338.py │ ├── 0018_auto_20181109_1844.py │ ├── 0019_project_project_short_description.py │ ├── 0020_volunteerrelation_is_co_owner.py │ ├── 0021_auto_20190108_0259.py │ ├── 0022_auto_20190211_1847.py │ ├── 0023_auto_20190319_2004.py │ ├── 0024_auto_20190326_0057.py │ ├── 0025_add_field_deleted.py │ ├── 0026_auto_20190522_0219.py │ ├── 0027_auto_20190717_1947.py │ ├── 0028_auto_20190722_2239.py │ ├── 0029_projectcommit.py │ ├── 0030_auto_20200501_1755.py │ ├── 0030_project_project_location_coords.py │ ├── 0031_auto_20200602_1535.py │ ├── 0031_event_event_live_id.py │ ├── 0032_auto_20200507_1934.py │ ├── 0033_merge_20200602_2359.py │ ├── 0034_auto_20200630_0220.py │ ├── 0035_group_group_location.py │ ├── 0036_auto_20200708_2251.py │ ├── 0037_projectrelationship_introduction_text.py │ ├── 0038_event_event_organizers_text.py │ ├── 0039_project_full_text.py │ ├── 0040_auto_20201030_0252.py │ ├── 0041_namerecord.py │ ├── 0042_auto_20210303_0016.py │ ├── 0043_auto_20210415_1648.py │ ├── 0044_volunteerrelation_is_team_leader.py │ ├── 0045_auto_20210515_2108.py │ ├── 0046_event_show_headers.py │ ├── 0047_auto_20210617_1900.py │ ├── 0048_auto_20210618_0024.py │ ├── 0049_projectfavorite.py │ ├── 0050_trelloaction.py │ ├── 0051_auto_20211028_0631.py │ ├── 0051_trelloaction_member_avatar_base_url.py │ ├── 0052_merge_20211029_0516.py │ ├── 0053_trelloaction_action_data.py │ ├── 0054_auto_20211205_1204.py │ ├── 0055_auto_20220216_1751.py │ ├── 0056_project_event_created_from.py │ ├── 0057_auto_20220324_1937.py │ ├── 0058_auto_20220414_2207.py │ ├── 0059_eventconferenceroomparticipant.py │ ├── 0060_auto_20220713_0309.py │ ├── 0061_auto_20221201_1842.py │ ├── 0062_auto_20230112_0100.py │ ├── 0063_alter_taggedcategory_tag_and_more.py │ ├── __init__.py │ ├── data_migrations │ │ ├── backfill_uuid.py │ │ ├── migrate_event_projects.py │ │ ├── migrate_location.py │ │ └── upload_oauth_thumbnails.py │ └── sql │ │ └── reverse_project_lat_long.sql ├── models.py ├── serializers.py ├── sitemaps.py ├── static │ ├── css │ │ ├── _bootstrapoverride.scss │ │ ├── _vars.scss │ │ ├── partials │ │ │ ├── _AboutEvent.scss │ │ │ ├── _AboutGroupDisplay.scss │ │ │ ├── _AboutProject.scss │ │ │ ├── _AboutProjectEventDisplay.scss │ │ │ ├── _AboutUs.scss │ │ │ ├── _AboutUser.scss │ │ │ ├── _AlertHeader.scss │ │ │ ├── _AllowMarkdown.scss │ │ │ ├── _ApproveGroupsSection.scss │ │ │ ├── _BioModal.scss │ │ │ ├── _Carousels.scss │ │ │ ├── _CollapsibleMenuItem.scss │ │ │ ├── _CollapsibleText.scss │ │ │ ├── _ContactUs.scss │ │ │ ├── _CorporateHackathon.scss │ │ │ ├── _CreateForm.scss │ │ │ ├── _CreateProjectForm.scss │ │ │ ├── _DonateController.scss │ │ │ ├── _DropDownMenuItem.scss │ │ │ ├── _EmailVerifiedController.scss │ │ │ ├── _FavoriteToggle.scss │ │ │ ├── _FileSelectButton.scss │ │ │ ├── _FileUploadList.scss │ │ │ ├── _FindEventController.scss │ │ │ ├── _FindProjectsController.scss │ │ │ ├── _FlashMessage.scss │ │ │ ├── _Fonts.scss │ │ │ ├── _Forms.scss │ │ │ ├── _Global.scss │ │ │ ├── _IconLinkDisplay.scss │ │ │ ├── _ImageCropUploadButton.scss │ │ │ ├── _JoinConference.scss │ │ │ ├── _LandingController.scss │ │ │ ├── _LatestBlogPosts.scss │ │ │ ├── _LinkList.scss │ │ │ ├── _LiveEvent.scss │ │ │ ├── _LoadingFrame.scss │ │ │ ├── _LoadingMessage.scss │ │ │ ├── _LogInController.scss │ │ │ ├── _MainHeader.scss │ │ │ ├── _MyEvents.scss │ │ │ ├── _MyProjectCard.scss │ │ │ ├── _MyProjectsController.scss │ │ │ ├── _Newsletter.scss │ │ │ ├── _PersonIcon.scss │ │ │ ├── _PositionList.scss │ │ │ ├── _Press.scss │ │ │ ├── _Privacy.scss │ │ │ ├── _Profile.scss │ │ │ ├── _ProjectCard.scss │ │ │ ├── _ProjectCardContainer.scss │ │ │ ├── _ProjectCardsContainer.scss │ │ │ ├── _ProjectCommitCard.scss │ │ │ ├── _ProjectFilterContainer.scss │ │ │ ├── _ProjectProfileSearch.scss │ │ │ ├── _ProjectSearchBar.scss │ │ │ ├── _ProjectSearchSort.scss │ │ │ ├── _ProjectTag.scss │ │ │ ├── _ProjectTagContainer.scss │ │ │ ├── _RecentProjects.scss │ │ │ ├── _ResetSearchButton.scss │ │ │ ├── _SectionLink.scss │ │ │ ├── _SignUpController.scss │ │ │ ├── _SignedUpController.scss │ │ │ ├── _SiteFooter.scss │ │ │ ├── _SplashScreen.scss │ │ │ ├── _SponsorFooter.scss │ │ │ ├── _StepIndicatorBars.scss │ │ │ ├── _Terms.scss │ │ │ ├── _ThankYouController.scss │ │ │ ├── _Toasts.scss │ │ │ ├── _Video.scss │ │ │ ├── _VolunteerCard.scss │ │ │ └── _base.scss │ │ ├── styles.scss │ │ └── vendor │ │ │ ├── _react-select.min.scss │ │ │ ├── bootstrap │ │ │ ├── _alert.scss │ │ │ ├── _badge.scss │ │ │ ├── _breadcrumb.scss │ │ │ ├── _button-group.scss │ │ │ ├── _buttons.scss │ │ │ ├── _card.scss │ │ │ ├── _carousel.scss │ │ │ ├── _close.scss │ │ │ ├── _code.scss │ │ │ ├── _custom-forms.scss │ │ │ ├── _dropdown.scss │ │ │ ├── _forms.scss │ │ │ ├── _functions.scss │ │ │ ├── _grid.scss │ │ │ ├── _images.scss │ │ │ ├── _input-group.scss │ │ │ ├── _jumbotron.scss │ │ │ ├── _list-group.scss │ │ │ ├── _media.scss │ │ │ ├── _mixins.scss │ │ │ ├── _modal.scss │ │ │ ├── _nav.scss │ │ │ ├── _navbar.scss │ │ │ ├── _pagination.scss │ │ │ ├── _popover.scss │ │ │ ├── _print.scss │ │ │ ├── _progress.scss │ │ │ ├── _reboot.scss │ │ │ ├── _root.scss │ │ │ ├── _spinners.scss │ │ │ ├── _tables.scss │ │ │ ├── _toasts.scss │ │ │ ├── _tooltip.scss │ │ │ ├── _transitions.scss │ │ │ ├── _type.scss │ │ │ ├── _utilities.scss │ │ │ ├── _variables.scss │ │ │ ├── bootstrap-grid.scss │ │ │ ├── bootstrap-reboot.scss │ │ │ ├── bootstrap.scss │ │ │ ├── mixins │ │ │ │ ├── _alert.scss │ │ │ │ ├── _background-variant.scss │ │ │ │ ├── _badge.scss │ │ │ │ ├── _border-radius.scss │ │ │ │ ├── _box-shadow.scss │ │ │ │ ├── _breakpoints.scss │ │ │ │ ├── _buttons.scss │ │ │ │ ├── _caret.scss │ │ │ │ ├── _clearfix.scss │ │ │ │ ├── _deprecate.scss │ │ │ │ ├── _float.scss │ │ │ │ ├── _forms.scss │ │ │ │ ├── _gradients.scss │ │ │ │ ├── _grid-framework.scss │ │ │ │ ├── _grid.scss │ │ │ │ ├── _hover.scss │ │ │ │ ├── _image.scss │ │ │ │ ├── _list-group.scss │ │ │ │ ├── _lists.scss │ │ │ │ ├── _nav-divider.scss │ │ │ │ ├── _pagination.scss │ │ │ │ ├── _reset-text.scss │ │ │ │ ├── _resize.scss │ │ │ │ ├── _screen-reader.scss │ │ │ │ ├── _size.scss │ │ │ │ ├── _table-row.scss │ │ │ │ ├── _text-emphasis.scss │ │ │ │ ├── _text-hide.scss │ │ │ │ ├── _text-truncate.scss │ │ │ │ ├── _transition.scss │ │ │ │ └── _visibility.scss │ │ │ ├── utilities │ │ │ │ ├── _align.scss │ │ │ │ ├── _background.scss │ │ │ │ ├── _borders.scss │ │ │ │ ├── _clearfix.scss │ │ │ │ ├── _display.scss │ │ │ │ ├── _embed.scss │ │ │ │ ├── _flex.scss │ │ │ │ ├── _float.scss │ │ │ │ ├── _overflow.scss │ │ │ │ ├── _position.scss │ │ │ │ ├── _screenreaders.scss │ │ │ │ ├── _shadows.scss │ │ │ │ ├── _sizing.scss │ │ │ │ ├── _spacing.scss │ │ │ │ ├── _stretched-link.scss │ │ │ │ ├── _text.scss │ │ │ │ └── _visibility.scss │ │ │ └── vendor │ │ │ │ └── _rfs.scss │ │ │ ├── react-datepicker │ │ │ └── _react-datepicker.scss │ │ │ └── react-image-crop │ │ │ └── ReactCrop.scss │ └── images │ │ ├── getstarted.png │ │ ├── login.png │ │ ├── logo.png │ │ ├── projectPlaceholder.png │ │ └── projectlogo-default.png ├── templates │ ├── googlebb20bcf8545e7046.html │ ├── new_index.html │ ├── robots.txt │ └── scripts │ │ ├── google_snippet.txt │ │ ├── google_tag_manager_snippet_body.txt │ │ ├── google_tag_manager_snippet_head.txt │ │ ├── hotjar_snippet.txt │ │ └── org_snippet.txt ├── tests │ ├── __init__.py │ └── test_views.py ├── urls.py └── views.py ├── common ├── __init__.py ├── admin.py ├── apps.py ├── caching │ ├── __init__.py │ └── cache.py ├── components │ ├── chrome │ │ ├── AlertHeader.jsx │ │ ├── FlashMessage.jsx │ │ ├── IconToggle.jsx │ │ ├── LoadingFrame.jsx │ │ ├── LoadingMessage.jsx │ │ ├── MainHeader.jsx │ │ ├── PseudoLink.jsx │ │ ├── SiteFooter.jsx │ │ └── SponsorFooter.jsx │ ├── common │ │ ├── CollapsiblePreviewPanel.jsx │ │ ├── CollapsibleTextSection.jsx │ │ ├── FeedbackModal.jsx │ │ ├── FileInfo.jsx │ │ ├── IframeResizerInParent.jsx │ │ ├── JumpAnchor.jsx │ │ ├── ModalWrapper.jsx │ │ ├── PromptNavigationModal.jsx │ │ ├── StepIndicatorBars.jsx │ │ ├── Visibility.jsx │ │ ├── WarningModal.jsx │ │ ├── avatar.jsx │ │ ├── carousel │ │ │ ├── BlogCarousel.jsx │ │ │ └── TestimonialCarousel.jsx │ │ ├── confirmation │ │ │ ├── ConfirmationModal.jsx │ │ │ ├── TermsModal.jsx │ │ │ └── TermsText.jsx │ │ ├── datetime │ │ │ └── DateRangeSelectors.jsx │ │ ├── event_projects │ │ │ ├── AboutProjectEventDisplay.jsx │ │ │ ├── ContactEventVolunteersButton.jsx │ │ │ ├── EventProjectRSVPModal.jsx │ │ │ ├── JoinConferenceButton.jsx │ │ │ └── RSVPVolunteerCard.jsx │ │ ├── events │ │ │ ├── LocationTimezoneSelector.jsx │ │ │ └── RemoteInPersonSelector.jsx │ │ ├── groups │ │ │ ├── AboutGroupDisplay.jsx │ │ │ ├── ContactGroupButton.jsx │ │ │ ├── GroupDetails.jsx │ │ │ └── IframeGroupDisplay.jsx │ │ ├── integrations │ │ │ ├── NewsletterSignup.jsx │ │ │ ├── PaypalDonationButton.jsx │ │ │ └── SocialMediaSignupSection.jsx │ │ ├── location │ │ │ ├── LocationAutocomplete.jsx │ │ │ ├── LocationInfo.js │ │ │ └── LocationRadius.js │ │ ├── notification │ │ │ ├── NotificationModal.jsx │ │ │ ├── Toast.jsx │ │ │ └── VerifyEmailBlurb.jsx │ │ ├── owners │ │ │ ├── ProjectOwnerCard.jsx │ │ │ └── ProjectOwnersSection.jsx │ │ ├── positions │ │ │ └── AboutPositionEntry.jsx │ │ ├── projects │ │ │ ├── AboutProjectDisplay.jsx │ │ │ ├── ApproveGroupsSection.jsx │ │ │ ├── ContactModal.jsx │ │ │ ├── ContactProjectButton.jsx │ │ │ ├── ContactVolunteersButton.jsx │ │ │ ├── InviteProjectToGroupButton.jsx │ │ │ ├── InviteProjectToGroupModal.jsx │ │ │ ├── ProfileProjectSearch.jsx │ │ │ ├── ProjectVolunteerButton.jsx │ │ │ ├── ProjectVolunteerConcludeModal.jsx │ │ │ ├── ProjectVolunteerModal.jsx │ │ │ ├── ProjectVolunteerRenewModal.jsx │ │ │ └── RecentActivityCard │ │ │ │ ├── ProjectCommitCard.jsx │ │ │ │ ├── TrelloActionCard.jsx │ │ │ │ └── components │ │ │ │ └── ActionAuthorLine.jsx │ │ ├── richtext │ │ │ └── AllowMarkdown.jsx │ │ ├── search │ │ │ ├── EntitySearchBar.jsx │ │ │ ├── EntitySearchSort.jsx │ │ │ └── EntityTagContainer.jsx │ │ ├── selection │ │ │ ├── CheckBox.jsx │ │ │ ├── CountrySelector.jsx │ │ │ ├── FormSelector.jsx │ │ │ ├── RadioButtons.jsx │ │ │ └── Selector.jsx │ │ ├── tags │ │ │ ├── TagCategory.jsx │ │ │ ├── TagSelectWrapper.jsx │ │ │ ├── TagSelector.jsx │ │ │ └── TagsDisplay.jsx │ │ ├── upload │ │ │ ├── FileSelectButton.jsx │ │ │ ├── FileUploadButton.jsx │ │ │ ├── ImageCropUploadButton.jsx │ │ │ └── S3Data.jsx │ │ ├── video │ │ │ ├── VideoModal.jsx │ │ │ └── VideoWrapper.jsx │ │ └── volunteers │ │ │ ├── VolunteerCard.jsx │ │ │ └── VolunteerSection.jsx │ ├── componentsBySection │ │ ├── AboutProject │ │ │ └── IconLinkDisplay.jsx │ │ ├── AboutUs │ │ │ ├── BioModal.jsx │ │ │ ├── BioPersonData.jsx │ │ │ ├── BioThumbnail.jsx │ │ │ └── TeamSections.jsx │ │ ├── AboutUser │ │ │ ├── EditUserBioModal.jsx │ │ │ ├── EditUserFilesModal.jsx │ │ │ ├── EditUserLinksModal.jsx │ │ │ ├── EditUserModal.jsx │ │ │ ├── EditUserNameModal.jsx │ │ │ ├── EditUserTagsModal.jsx │ │ │ └── EditUserThumbnailModal.jsx │ │ ├── CreateEvent │ │ │ ├── AboutEventDisplay.jsx │ │ │ ├── EventDescriptionForm.jsx │ │ │ ├── EventFormCommon.jsx │ │ │ ├── EventOverviewForm.jsx │ │ │ └── EventPreviewForm.jsx │ │ ├── CreateEventProject │ │ │ ├── CreateEventProjectScope.jsx │ │ │ ├── CreateEventProjectSelect.jsx │ │ │ ├── EventProjectPositionsForm.jsx │ │ │ └── EventProjectResourcesForm.jsx │ │ ├── CreateGroup │ │ │ ├── GroupFormCommon.jsx │ │ │ ├── GroupOverviewForm.jsx │ │ │ ├── GroupPreviewForm.jsx │ │ │ └── GroupResourcesForm.jsx │ │ ├── CreateProject │ │ │ ├── ProjectDescriptionForm.jsx │ │ │ ├── ProjectFormCommon.jsx │ │ │ ├── ProjectInfoForm.jsx │ │ │ ├── ProjectOverviewForm.jsx │ │ │ ├── ProjectPositionsForm.jsx │ │ │ ├── ProjectPreviewForm.jsx │ │ │ └── ProjectResourcesForm.jsx │ │ ├── Donate │ │ │ └── DonateBlurb.jsx │ │ ├── FindEvents │ │ │ ├── EventCard.jsx │ │ │ ├── EventCardsContainer.jsx │ │ │ └── EventCardsListings.jsx │ │ ├── FindGroups │ │ │ ├── FIlters │ │ │ │ ├── GroupFilterContainer.jsx │ │ │ │ └── GroupFilterDataContainer.jsx │ │ │ ├── GroupCard.jsx │ │ │ └── GroupCardsContainer.jsx │ │ ├── FindProjects │ │ │ ├── AlertSignupModal.jsx │ │ │ ├── CloseablePill.jsx │ │ │ ├── FavoriteFilter.jsx │ │ │ ├── FavoriteToggle.jsx │ │ │ ├── Filters │ │ │ │ ├── LocationSearchSection.jsx │ │ │ │ ├── ProjectFilterContainer.jsx │ │ │ │ ├── ProjectFilterDataContainer.jsx │ │ │ │ └── RenderFilterCategory.jsx │ │ │ ├── ProjectCard.jsx │ │ │ ├── ProjectCardsContainer.jsx │ │ │ ├── ProjectDetails.jsx │ │ │ ├── ProjectSearchContainer.jsx │ │ │ ├── ResetSearchButton.jsx │ │ │ └── SplashScreen.jsx │ │ ├── Landing │ │ │ ├── LatestBlogPosts.jsx │ │ │ ├── RecentProjectsSection.jsx │ │ │ └── UpcomingEventCard.jsx │ │ ├── MyGroups │ │ │ └── MyGroupsCard.jsx │ │ ├── MyProjects │ │ │ └── MyProjectCard.jsx │ │ └── signUp │ │ │ └── SignUpErrorAdapter.jsx │ ├── constants │ │ ├── Countries.js │ │ ├── FileConstants.js │ │ └── LinkConstants.js │ ├── controllers │ │ ├── AboutEventController.jsx │ │ ├── AboutEventProjectController.jsx │ │ ├── AboutGroupController.jsx │ │ ├── AboutProjectController.jsx │ │ ├── AboutUsController.jsx │ │ ├── AboutUserController.jsx │ │ ├── AddSignUpDetails.jsx │ │ ├── ChangePasswordController.jsx │ │ ├── ContactUsController.jsx │ │ ├── CorporateHackathonController.jsx │ │ ├── CreateEventController.jsx │ │ ├── CreateEventProjectController.jsx │ │ ├── CreateGroupController.jsx │ │ ├── CreateProjectController.jsx │ │ ├── DonateController.jsx │ │ ├── EmailVerifiedController.jsx │ │ ├── ErrorController.jsx │ │ ├── FindEventsController.jsx │ │ ├── FindGroupsController.jsx │ │ ├── FindProjectsController.jsx │ │ ├── IframeGroupController.jsx │ │ ├── LandingController.jsx │ │ ├── LiveEventController.jsx │ │ ├── LogInController.jsx │ │ ├── MainController.jsx │ │ ├── MyEventsController.jsx │ │ ├── MyGroupsController.jsx │ │ ├── MyProjectsController.jsx │ │ ├── PressController.jsx │ │ ├── PrivacyController.jsx │ │ ├── ResetPasswordController.jsx │ │ ├── SectionController.jsx │ │ ├── SignUpController.jsx │ │ ├── SignedUpController.jsx │ │ ├── TermsController.jsx │ │ ├── ThankYouController.jsx │ │ └── VideoController.jsx │ ├── enums │ │ ├── IssueArea.js │ │ └── Section.js │ ├── forms │ │ ├── CharacterCounter.jsx │ │ ├── ContactForm.jsx │ │ ├── FileUploadList.jsx │ │ ├── FormValidation.jsx │ │ ├── FormWorkflow.jsx │ │ ├── HiddenFormFields.jsx │ │ ├── ImageCropUploadFormElement.jsx │ │ ├── InlineFormError.jsx │ │ ├── LinkEntryModal.jsx │ │ ├── LinkInfo.jsx │ │ ├── LinkList.jsx │ │ ├── LocationAutocompleteForm.jsx │ │ ├── PositionEntryModal.jsx │ │ ├── PositionInfo.jsx │ │ ├── PositionList.jsx │ │ ├── PositionListEntry.jsx │ │ └── fields │ │ │ ├── CountryLocationFormFields.jsx │ │ │ └── TextFormField.jsx │ ├── mount-components.js │ ├── stores │ │ ├── EntitySearchStore.js │ │ ├── FavoritesStore.js │ │ ├── FormFieldsStore.js │ │ ├── NavigationStore.js │ │ ├── PageOffsetStore.js │ │ └── UniversalDispatcher.js │ ├── svg │ │ ├── arrowright-black.svg │ │ ├── arrowright-orange.svg │ │ ├── corporatehackathon │ │ │ ├── Code.svg │ │ │ ├── ConnectionCircle.svg │ │ │ ├── Discover.svg │ │ │ ├── Megaphone.svg │ │ │ ├── one.svg │ │ │ ├── three.svg │ │ │ └── two.svg │ │ ├── default-activity-feed-avatar.svg │ │ ├── facebook.svg │ │ ├── github.svg │ │ ├── google.svg │ │ ├── homepage │ │ │ ├── chart.svg │ │ │ ├── green-split-dot.svg │ │ │ ├── red-dot.svg │ │ │ └── yellow-dot.svg │ │ ├── linkedin.svg │ │ ├── person.svg │ │ ├── play-button.svg │ │ ├── recruit1.svg │ │ ├── recruit2.svg │ │ ├── recruit3.svg │ │ ├── user-circle-solid.svg │ │ ├── volunteer1.svg │ │ ├── volunteer2.svg │ │ └── volunteer3.svg │ ├── test │ │ ├── __mocks__ │ │ │ ├── mockAPI.js │ │ │ └── window.js │ │ ├── common.test.js │ │ ├── componentsBySection.test.js │ │ ├── controllers.test.js │ │ ├── string.test.js │ │ ├── utils.test.js │ │ └── validation.test.js │ ├── types │ │ ├── Generics.jsx │ │ ├── HereTypes.jsx │ │ └── SelectOption.jsx │ ├── urls │ │ ├── urls_v1.json │ │ └── urls_v2.json │ └── utils │ │ ├── CurrentUser.js │ │ ├── EventAPIUtils.js │ │ ├── EventProjectAPIUtils.js │ │ ├── GroupAPIUtils.js │ │ ├── NavigationLinks.js │ │ ├── ProjectAPIUtils.js │ │ ├── Sponsors.js │ │ ├── UserAPIUtils.js │ │ ├── api.js │ │ ├── array.js │ │ ├── async.js │ │ ├── cdn.js │ │ ├── datetime.js │ │ ├── forms.js │ │ ├── ghostApi.js │ │ ├── glyphs.js │ │ ├── groupBy.js │ │ ├── guard.js │ │ ├── heapApi.js │ │ ├── hereApi.js │ │ ├── htmlDocument.js │ │ ├── iframe.js │ │ ├── metrics.js │ │ ├── promise.js │ │ ├── s3.js │ │ ├── sort.js │ │ ├── string.js │ │ ├── truncate.js │ │ ├── url.js │ │ ├── utils.js │ │ └── validation.js ├── fixtures │ ├── testdata readme.txt │ ├── testdata.json │ └── testdata_pre_migrate.json ├── helpers │ ├── __init__.py │ ├── collections.py │ ├── constants.py │ ├── date_helpers.py │ ├── db.py │ ├── dictionaries.py │ ├── error_handlers.py │ ├── form_helpers.py │ ├── front_end.py │ ├── github.py │ ├── mailing_list.py │ ├── malicious_requests.py │ ├── qiqo_chat.py │ ├── queue.py │ ├── random.py │ ├── redirectors.py │ ├── request_helpers.py │ ├── retry.py │ ├── s3.py │ ├── tags.py │ ├── trello.py │ └── user_helpers.py ├── management │ └── commands │ │ ├── __init__.py │ │ ├── activate_event.py │ │ ├── cache_initialization.py │ │ ├── deactivate_event.py │ │ ├── emailreminders.py │ │ ├── merge_with_salesforce.py │ │ ├── project_external_updates.py │ │ ├── tags_csv.py │ │ └── volunteer_renewal_reminders.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_auto_20190501_1846.py │ └── __init__.py ├── models │ ├── Tag_definitions.csv │ ├── __init__.py │ ├── tags.py │ └── visibility.py ├── static │ ├── css │ │ └── react-select.min.css │ └── js │ │ └── selection.js ├── tests │ ├── __init__.py │ ├── test_collections.py │ ├── test_helpers.py │ ├── test_redirectors.py │ └── test_trello_helpers.py └── urls.py ├── democracylab ├── __init__.py ├── admin.py ├── apps.py ├── emails.py ├── forms.py ├── logging.py ├── migrations │ ├── 0001_initial.py │ ├── 0002_contributor_email_verified.py │ ├── 0003_auto_20180911_0124.py │ ├── 0004_auto_20190429_1929.py │ ├── 0005_auto_20190503_2237.py │ ├── 0006_auto_20200427_2336.py │ ├── 0007_backfill_user_uuids.py │ ├── 0008_contributor_qiqo_signup_time.py │ ├── 0009_auto_20210302_2036.py │ ├── 0010_alter_usertaggedtechnologies_tag.py │ └── __init__.py ├── models.py ├── settings.py ├── templates │ ├── aboutme.html │ ├── account │ │ └── messages │ │ │ └── logged_in.txt │ ├── base.html │ ├── emails │ │ ├── html_email_button.html │ │ ├── html_email_frame.html │ │ ├── html_email_header.html │ │ ├── html_email_headerleft.html │ │ ├── html_email_paragraph.html │ │ ├── html_email_paragraph_center.html │ │ ├── html_email_subheader.html │ │ └── html_email_text_line.html │ ├── index.html │ └── registration │ │ ├── password_reset_complete.html │ │ ├── password_reset_confirm.html │ │ ├── password_reset_done.html │ │ ├── password_reset_email.html │ │ ├── password_reset_form.html │ │ └── password_reset_subject.txt ├── tokens.py ├── urls.py ├── views.py └── wsgi.py ├── democracylab_environment_variables.sh ├── docker-compose.yml ├── example.env ├── manage.py ├── newrelic.ini ├── oauth2 ├── __init__.py ├── adapter.py ├── app_settings.py ├── apps.py ├── providers │ ├── facebook │ │ ├── __init__.py │ │ ├── data │ │ │ └── FacebookLocales.xml │ │ ├── forms.py │ │ ├── locale.py │ │ ├── provider.py │ │ ├── static │ │ │ └── facebook │ │ │ │ └── js │ │ │ │ └── fbconnect.js │ │ ├── templates │ │ │ └── facebook │ │ │ │ └── fbconnect.html │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── github │ │ ├── __init__.py │ │ ├── provider.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ ├── google │ │ ├── __init__.py │ │ ├── provider.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py │ └── linkedin │ │ ├── __init__.py │ │ ├── provider.py │ │ ├── tests.py │ │ ├── urls.py │ │ └── views.py └── socialapp.py ├── package.json ├── release-tasks.sh ├── requirements.txt ├── salesforce ├── README ├── __init__.py ├── apps.py ├── campaign.py ├── client.py ├── contact.py ├── volunteer_hours.py └── volunteer_job.py ├── setupJest.js ├── tools ├── iframe-test-resizer.html └── iframe-test.html ├── webpack.common.js ├── webpack.dev.js ├── webpack.prod.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | /* 2 | ./.babelrc 3 | */ 4 | { 5 | "presets":[ 6 | "@babel/preset-env", 7 | "@babel/preset-react", 8 | "@babel/preset-flow", 9 | ] 10 | } 11 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Ignore all files and only allow files and directories below. 2 | * 3 | 4 | # Working folders. 5 | !civictechprojects/ 6 | !common/ 7 | !democracylab/ 8 | !oauth2/ 9 | !salesforce/ 10 | 11 | # Important run-time files. 12 | !manage.py 13 | !setupJest.js 14 | !webpack.config.js 15 | !.babelrc 16 | 17 | # Third-party dependency files. 18 | !package.json 19 | !yarn.lock 20 | !.yarnrc 21 | !requirements.txt 22 | 23 | # Config 24 | !webpack.common.js 25 | !webpack.prod.js 26 | !docker_environment_init.sh -------------------------------------------------------------------------------- /.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | node_modules 3 | 4 | [include] 5 | 6 | [libs] 7 | 8 | [lints] 9 | 10 | [options] 11 | 12 | [strict] 13 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: DemocracyLab 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | default_language_version: 2 | python: python3.8 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v4.3.0 6 | hooks: 7 | - id: end-of-file-fixer 8 | - id: trailing-whitespace 9 | - repo: https://github.com/psf/black 10 | rev: 22.8.0 11 | hooks: 12 | - id: black 13 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Prettier ignore config - https://prettier.io/docs/en/ignore.html 2 | 3 | # This model acts to disallow by default and then enable for specific file types; then exclude within those file types selectively, e.g. include our css, don't include third-party css 4 | 5 | # disallow everything, even extensionless files 6 | * 7 | # allow directories so the below rules can take effect 8 | !*/ 9 | 10 | 11 | ### Allowed File Types ### 12 | 13 | # javascript 14 | !*.jsx 15 | !*.js 16 | !*.json 17 | 18 | 19 | # css/sass 20 | !*.scss 21 | !*.css 22 | 23 | # markdown 24 | !*.md 25 | 26 | 27 | 28 | ### Exceptions ### 29 | 30 | # disallow third-party files 31 | **/vendor/** 32 | 33 | # disallow build location 34 | staticfiles/** 35 | 36 | # disallow bundles and already minified files 37 | *.bundle.js 38 | *.min.js 39 | *.min.css 40 | webpack.*.js 41 | 42 | 43 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "trailingComma": "es5", 3 | "tabWidth": 2, 4 | "semi": true, 5 | "singleQuote": false 6 | } 7 | -------------------------------------------------------------------------------- /.python-version: -------------------------------------------------------------------------------- 1 | 3.10.16 -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 DemocracyLab 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: newrelic-admin run-program gunicorn democracylab.wsgi 2 | release: ./release-tasks.sh 3 | worker: python manage.py rqworker -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CivicTechExchange", 3 | "scripts": {}, 4 | "env": { 5 | "AWS_ACCESS_KEY_ID": { 6 | "required": true 7 | }, 8 | "AWS_SECRET_ACCESS_KEY": { 9 | "required": true 10 | }, 11 | "S3_BUCKET": { 12 | "required": true 13 | }, 14 | "DJANGO_DEBUG": { 15 | "required": true 16 | }, 17 | "ADMIN_EMAIL": { 18 | "required": true 19 | }, 20 | "DJANGO_SECRET_KEY": { 21 | "required": true, 22 | "generator": "secret" 23 | }, 24 | "PROTOCOL_DOMAIN": { 25 | "required": true 26 | }, 27 | "DISABLE_COLLECTSTATIC": { 28 | "description": "Don't run python manage.py collectstatic --noinput on deploy", 29 | "value": "1" 30 | } 31 | }, 32 | "formation": { 33 | "web": { 34 | "quantity": 1 35 | } 36 | }, 37 | "addons": ["heroku-postgresql"], 38 | "buildpacks": [ 39 | { 40 | "url": "heroku/python" 41 | } 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /civic.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "DemocracyLab", 3 | "description": "Building online infrastructure to empower the civic tech movement. Our initial iteration connects volunteers to tech-for-good projects.", 4 | "license": "MIT", 5 | "status": "Production", 6 | "type": "Web app", 7 | "homepage": "https://www.democracylab.org", 8 | "repository": "https://github.com/DemocracyLab/CivicTechExchange", 9 | "thumbnail": "https://democracylab-marlok.s3.amazonaws.com/thumbnails%2Fmark%40democracylab.org%2Fdl_idnty_node_mark.png_1517778401.9664516.png", 10 | "geography": [], 11 | "contact": { 12 | "name": "Mark Frischmuth", 13 | "email": "hello@democracylab.org", 14 | "url": "" 15 | }, 16 | "partners": [], 17 | "data": [], 18 | "tags": [], 19 | "links": ["https://www.democracylab.org/projects/1"], 20 | "id": "https://raw.githubusercontent.com/DCgov/civic.json/master/schemas/schema-v1.json" 21 | } 22 | -------------------------------------------------------------------------------- /civictechprojects/__init__.py: -------------------------------------------------------------------------------- 1 | INSTALLED_APPS = [ 2 | 'civictechprojects.apps.CivictechprojectsConfig', 3 | 'oauth2.apps.OAuth2Config', 4 | 'django.contrib.admin', 5 | 'django.contrib.auth', 6 | 'django.contrib.contenttypes', 7 | 'django.contrib.sessions', 8 | 'django.contrib.messages', 9 | 'django.contrib.staticfiles', 10 | ] -------------------------------------------------------------------------------- /civictechprojects/apps.py: -------------------------------------------------------------------------------- 1 | from django.apps import AppConfig 2 | 3 | 4 | class CivictechprojectsConfig(AppConfig): 5 | name = 'civictechprojects' 6 | 7 | # def ready(self): 8 | # Remove any tags that aren't in the canonical tag list 9 | # TODO: Fix so this doesn't break in production database if we need to clean up tags again 10 | # from .models import Project 11 | # Project.remove_tags_not_in_list() 12 | 13 | -------------------------------------------------------------------------------- /civictechprojects/caching/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/caching/__init__.py -------------------------------------------------------------------------------- /civictechprojects/helpers/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/helpers/__init__.py -------------------------------------------------------------------------------- /civictechprojects/helpers/search/common.py: -------------------------------------------------------------------------------- 1 | from common.helpers.tags import get_tag_dictionary 2 | 3 | 4 | def apply_tag_filters(project_list, query_params, param_name, tag_filter): 5 | if param_name in query_params: 6 | tag_dict = get_tag_dictionary() 7 | tags_to_filter_by = query_params[param_name][0].split(',') 8 | tags_to_filter_by = clean_nonexistent_tags(tags_to_filter_by, tag_dict) 9 | if len(tags_to_filter_by): 10 | project_list = project_list & tag_filter(tags_to_filter_by) 11 | 12 | return project_list 13 | 14 | 15 | def clean_nonexistent_tags(tags, tag_dict): 16 | return list(filter(lambda tag: tag in tag_dict, tags)) 17 | 18 | 19 | def sort_by_field(project_list, sort_field): 20 | return project_list.order_by(sort_field) -------------------------------------------------------------------------------- /civictechprojects/migrations/0002_auto_20171119_2223.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2017-11-19 22:23 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0001_initial'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='project', 17 | name='project_issue_area', 18 | field=models.CharField(default='Political Reform', max_length=200), 19 | preserve_default=False, 20 | ), 21 | migrations.AddField( 22 | model_name='project', 23 | name='project_location', 24 | field=models.CharField(default='Seattle, WA', max_length=200), 25 | preserve_default=False, 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0004_auto_20171221_0105.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2017-12-21 01:05 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('democracylab', '0001_initial'), 13 | ('civictechprojects', '0003_auto_20171125_2144'), 14 | ] 15 | 16 | operations = [ 17 | migrations.AddField( 18 | model_name='project', 19 | name='project_volunteers', 20 | field=models.ManyToManyField(related_name='volunteers', to='democracylab.Contributor'), 21 | ), 22 | migrations.AlterField( 23 | model_name='project', 24 | name='project_creator', 25 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='creator', to='democracylab.Contributor'), 26 | ), 27 | ] 28 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0006_auto_20180122_2215.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-01-22 22:15 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0005_auto_20180104_0438'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='project', 17 | name='project_url', 18 | field=models.CharField(blank=True, max_length=2083), 19 | ), 20 | migrations.AlterField( 21 | model_name='projectfile', 22 | name='file_url', 23 | field=models.CharField(max_length=2083), 24 | ), 25 | migrations.AlterField( 26 | model_name='projectlink', 27 | name='link_url', 28 | field=models.CharField(max_length=2083), 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0007_auto_20180317_1723.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-03-17 17:23 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0006_auto_20180122_2215'), 12 | ] 13 | 14 | operations = [ 15 | migrations.RemoveField( 16 | model_name='taggedtag', 17 | name='content_object', 18 | ), 19 | migrations.RemoveField( 20 | model_name='taggedtag', 21 | name='tag', 22 | ), 23 | migrations.RemoveField( 24 | model_name='project', 25 | name='project_tags', 26 | ), 27 | migrations.DeleteModel( 28 | name='TaggedTag', 29 | ), 30 | ] 31 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0010_auto_20180522_1923.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-05-22 19:23 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0009_auto_20180403_1604'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='project', 17 | name='is_searchable', 18 | field=models.BooleanField(default=True), 19 | ), 20 | migrations.AlterField( 21 | model_name='project', 22 | name='project_volunteers', 23 | field=models.ManyToManyField(blank=True, related_name='volunteers', to='democracylab.Contributor'), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0011_auto_20180529_0426.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-05-29 04:26 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0010_auto_20180522_1923'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='projectposition', 17 | name='description_url', 18 | field=models.CharField(default='', max_length=2083), 19 | ), 20 | migrations.AlterField( 21 | model_name='projectposition', 22 | name='position_description', 23 | field=models.CharField(blank=True, max_length=3000), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0013_useralert.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-07-14 05:33 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0012_auto_20180626_1535'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='UserAlert', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('email', models.EmailField(max_length=254)), 20 | ('filters', models.CharField(max_length=2083)), 21 | ('country', models.CharField(max_length=2)), 22 | ('postal_code', models.CharField(max_length=20)), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0015_project_project_date_modified.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-08-22 15:26 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0014_auto_20180806_1942'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='project', 17 | name='project_date_modified', 18 | field=models.DateTimeField(auto_now=True, null=True), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0018_auto_20181109_1844.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-11-09 18:44 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('civictechprojects', '0017_auto_20181030_0338'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='volunteerrelation', 18 | name='projected_end_date', 19 | field=models.DateTimeField(null=True), 20 | ), 21 | migrations.AlterField( 22 | model_name='volunteerrelation', 23 | name='project', 24 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='volunteer_relations', to='civictechprojects.Project'), 25 | ), 26 | migrations.AlterField( 27 | model_name='volunteerrelation', 28 | name='volunteer', 29 | field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='volunteer_relations', to='democracylab.Contributor'), 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0019_project_project_short_description.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-11-15 16:22 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0018_auto_20181109_1844'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='project', 17 | name='project_short_description', 18 | field=models.CharField(blank=True, max_length=140), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0020_volunteerrelation_is_co_owner.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2018-12-05 03:35 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0019_project_project_short_description'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='volunteerrelation', 17 | name='is_co_owner', 18 | field=models.BooleanField(default=False), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0021_auto_20190108_0259.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2019-01-08 02:59 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.utils.timezone 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('civictechprojects', '0020_volunteerrelation_is_co_owner'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='volunteerrelation', 18 | name='application_date', 19 | field=models.DateTimeField(default=django.utils.timezone.now), 20 | ), 21 | migrations.AddField( 22 | model_name='volunteerrelation', 23 | name='last_reminder_date', 24 | field=models.DateTimeField(null=True), 25 | ), 26 | migrations.AddField( 27 | model_name='volunteerrelation', 28 | name='reminder_count', 29 | field=models.IntegerField(default=0), 30 | ), 31 | ] 32 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0022_auto_20190211_1847.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2019-02-11 18:47 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0021_auto_20190108_0259'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='project', 17 | name='project_date_created', 18 | field=models.DateTimeField(null=True), 19 | ), 20 | migrations.AddField( 21 | model_name='volunteerrelation', 22 | name='approved_date', 23 | field=models.DateTimeField(null=True), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0024_auto_20190326_0057.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.10.7 on 2019-03-26 07:57 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0023_auto_20190319_2004'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='project', 17 | name='project_date_modified', 18 | field=models.DateTimeField(auto_now_add=True, null=True), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0025_add_field_deleted.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | from __future__ import unicode_literals 3 | 4 | from django.db import migrations, models 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('civictechprojects', '0024_auto_20190326_0057'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='project', 16 | name='deleted', 17 | field=models.BooleanField(default=False), 18 | ), 19 | migrations.AddField( 20 | model_name='volunteerrelation', 21 | name='deleted', 22 | field=models.BooleanField(default=False) 23 | ) 24 | ] 25 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0026_auto_20190522_0219.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.20 on 2019-05-22 02:19 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0025_add_field_deleted'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='project', 17 | name='is_searchable', 18 | field=models.BooleanField(default=False), 19 | ), 20 | migrations.AlterField( 21 | model_name='project', 22 | name='project_location', 23 | field=models.CharField(blank=True, max_length=200), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0028_auto_20190722_2239.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.20 on 2019-07-22 22:39 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0027_auto_20190717_1947'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AlterField( 16 | model_name='projectfile', 17 | name='file_name', 18 | field=models.CharField(max_length=150), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0030_project_project_location_coords.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-05-25 15:44 3 | from __future__ import unicode_literals 4 | 5 | import django.contrib.gis.db.models.fields 6 | from django.db import migrations 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('civictechprojects', '0029_projectcommit'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='project', 18 | name='project_location_coords', 19 | field=django.contrib.gis.db.models.fields.PointField(blank=True, default='POINT EMPTY', null=True, srid=4326), 20 | ), 21 | ] 22 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0031_auto_20200602_1535.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-06-02 15:35 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | from civictechprojects.migrations.data_migrations.migrate_location import migrate_locations_from_city_list 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('civictechprojects', '0030_project_project_location_coords'), 13 | ] 14 | 15 | operations = [ 16 | migrations.AddField( 17 | model_name='project', 18 | name='project_city', 19 | field=models.CharField(blank=True, max_length=100), 20 | ), 21 | migrations.AddField( 22 | model_name='project', 23 | name='project_country', 24 | field=models.CharField(blank=True, max_length=100), 25 | ), 26 | migrations.AddField( 27 | model_name='project', 28 | name='project_state', 29 | field=models.CharField(blank=True, max_length=100), 30 | ), migrations.RunPython(migrate_locations_from_city_list, reverse_code=migrations.RunPython.noop) 31 | ] 32 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0031_event_event_live_id.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-05-06 04:17 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0030_auto_20200501_1755'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='event', 17 | name='event_live_id', 18 | field=models.CharField(blank=True, max_length=50), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0033_merge_20200602_2359.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-06-02 23:59 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0031_auto_20200602_1535'), 12 | ('civictechprojects', '0032_auto_20200507_1934'), 13 | ] 14 | 15 | operations = [ 16 | ] 17 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0035_group_group_location.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-06-30 16:49 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0034_auto_20200630_0220'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='group', 17 | name='group_location', 18 | field=models.CharField(blank=True, max_length=200), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0036_auto_20200708_2251.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-07-08 22:51 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0035_group_group_location'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='projectrelationship', 17 | name='is_approved', 18 | field=models.BooleanField(default=False), 19 | ), 20 | migrations.AddField( 21 | model_name='projectrelationship', 22 | name='project_initiated', 23 | field=models.BooleanField(default=False), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0037_projectrelationship_introduction_text.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-07-10 02:52 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0036_auto_20200708_2251'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='projectrelationship', 17 | name='introduction_text', 18 | field=models.CharField(blank=True, max_length=10000), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0038_event_event_organizers_text.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-08-10 19:35 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0037_projectrelationship_introduction_text'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='event', 17 | name='event_organizers_text', 18 | field=models.CharField(blank=True, max_length=200), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0039_project_full_text.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-09-28 14:39 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0038_event_event_organizers_text'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='project', 17 | name='full_text', 18 | field=models.CharField(blank=True, max_length=200000), 19 | ), 20 | ] 21 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0040_auto_20201030_0252.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-10-30 02:52 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0039_project_full_text'), 12 | ] 13 | 14 | operations = [ 15 | migrations.AddField( 16 | model_name='event', 17 | name='event_slug', 18 | field=models.CharField(blank=True, max_length=100), 19 | ), 20 | migrations.AddField( 21 | model_name='event', 22 | name='is_private', 23 | field=models.BooleanField(default=False), 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0041_namerecord.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # Generated by Django 1.11.28 on 2020-11-25 22:35 3 | from __future__ import unicode_literals 4 | 5 | from django.db import migrations, models 6 | import django.db.models.deletion 7 | 8 | 9 | class Migration(migrations.Migration): 10 | 11 | dependencies = [ 12 | ('civictechprojects', '0040_auto_20201030_0252'), 13 | ] 14 | 15 | operations = [ 16 | migrations.CreateModel( 17 | name='NameRecord', 18 | fields=[ 19 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 20 | ('name', models.CharField(blank=True, max_length=100)), 21 | ('event', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='old_slugs', to='civictechprojects.Event')), 22 | ], 23 | ), 24 | ] 25 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0044_volunteerrelation_is_team_leader.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.4 on 2021-04-27 15:02 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0043_auto_20210415_1648'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='volunteerrelation', 15 | name='is_team_leader', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0045_auto_20210515_2108.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.4 on 2021-05-15 21:08 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0044_volunteerrelation_is_team_leader'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='projectposition', 15 | name='is_hidden', 16 | field=models.BooleanField(default=False), 17 | ), 18 | migrations.AddField( 19 | model_name='projectposition', 20 | name='order_number', 21 | field=models.PositiveIntegerField(default=0), 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0046_event_show_headers.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-06-01 15:57 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0045_auto_20210515_2108'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='event', 15 | name='show_headers', 16 | field=models.BooleanField(default=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0047_auto_20210617_1900.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-06-17 19:00 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0046_event_show_headers'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='projectfile', 15 | name='file_name', 16 | field=models.CharField(max_length=300), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0048_auto_20210618_0024.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-06-18 00:24 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0047_auto_20210617_1900'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='projectfile', 15 | name='file_key', 16 | field=models.CharField(max_length=400), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0049_projectfavorite.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-09-21 16:45 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('democracylab', '0009_auto_20210302_2036'), 11 | ('civictechprojects', '0048_auto_20210618_0024'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='ProjectFavorite', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('link_project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='favorites', to='civictechprojects.project')), 20 | ('link_user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='favorites', to='democracylab.contributor')), 21 | ], 22 | ), 23 | ] 24 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0050_trelloaction.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-10-14 21:37 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('civictechprojects', '0049_projectfavorite'), 11 | ] 12 | 13 | operations = [ 14 | migrations.CreateModel( 15 | name='TrelloAction', 16 | fields=[ 17 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 18 | ('member_fullname', models.CharField(max_length=200)), 19 | ('member_id', models.CharField(max_length=2083)), 20 | ('board_id', models.CharField(max_length=2083)), 21 | ('action_type', models.CharField(max_length=2083)), 22 | ('action_date', models.DateTimeField()), 23 | ('action_project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='trello_actions', to='civictechprojects.project')), 24 | ], 25 | ), 26 | ] 27 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0051_auto_20211028_0631.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-10-28 06:31 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0050_trelloaction'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AlterField( 14 | model_name='trelloaction', 15 | name='id', 16 | field=models.CharField(max_length=2083, primary_key=True, serialize=False), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0051_trelloaction_member_avatar_base_url.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-10-27 21:23 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0050_trelloaction'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='trelloaction', 15 | name='member_avatar_base_url', 16 | field=models.CharField(blank=True, max_length=2083), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0052_merge_20211029_0516.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-10-29 05:16 2 | 3 | from django.db import migrations 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0051_trelloaction_member_avatar_base_url'), 10 | ('civictechprojects', '0051_auto_20211028_0631'), 11 | ] 12 | 13 | operations = [ 14 | ] 15 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0053_trelloaction_action_data.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.8 on 2021-11-02 13:27 2 | 3 | from django.db import migrations, models 4 | 5 | 6 | class Migration(migrations.Migration): 7 | 8 | dependencies = [ 9 | ('civictechprojects', '0052_merge_20211029_0516'), 10 | ] 11 | 12 | operations = [ 13 | migrations.AddField( 14 | model_name='trelloaction', 15 | name='action_data', 16 | field=models.JSONField(null=True), 17 | ), 18 | ] 19 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0056_project_event_created_from.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.13 on 2022-03-17 19:00 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('civictechprojects', '0055_auto_20220216_1751'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AddField( 15 | model_name='project', 16 | name='event_created_from', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_projects', to='civictechprojects.event'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0059_eventconferenceroomparticipant.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.13 on 2022-04-19 22:53 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | import django.utils.timezone 6 | 7 | 8 | class Migration(migrations.Migration): 9 | 10 | dependencies = [ 11 | ('civictechprojects', '0058_auto_20220414_2207'), 12 | ] 13 | 14 | operations = [ 15 | migrations.CreateModel( 16 | name='EventConferenceRoomParticipant', 17 | fields=[ 18 | ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), 19 | ('zoom_user_name', models.CharField(max_length=100)), 20 | ('zoom_user_id', models.BigIntegerField(default=0)), 21 | ('enter_date', models.DateTimeField(default=django.utils.timezone.now)), 22 | ('room', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='participants', to='civictechprojects.eventconferenceroom')), 23 | ], 24 | ), 25 | ] 26 | -------------------------------------------------------------------------------- /civictechprojects/migrations/0062_auto_20230112_0100.py: -------------------------------------------------------------------------------- 1 | # Generated by Django 3.1.14 on 2023-01-12 01:00 2 | 3 | from django.db import migrations, models 4 | import django.db.models.deletion 5 | 6 | 7 | class Migration(migrations.Migration): 8 | 9 | dependencies = [ 10 | ('civictechprojects', '0061_auto_20221201_1842'), 11 | ] 12 | 13 | operations = [ 14 | migrations.AlterField( 15 | model_name='eventproject', 16 | name='event_time_zone', 17 | field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='time_zone_event_projects', to='civictechprojects.eventlocationtimezone'), 18 | ), 19 | ] 20 | -------------------------------------------------------------------------------- /civictechprojects/migrations/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/migrations/__init__.py -------------------------------------------------------------------------------- /civictechprojects/migrations/data_migrations/backfill_uuid.py: -------------------------------------------------------------------------------- 1 | from democracylab.models import Contributor 2 | from common.helpers.random import generate_uuid 3 | 4 | 5 | def backfill_user_uuids(apps, schema_editor): 6 | for user in Contributor.objects.all(): 7 | user.uuid = generate_uuid() 8 | user.save() -------------------------------------------------------------------------------- /civictechprojects/migrations/sql/reverse_project_lat_long.sql: -------------------------------------------------------------------------------- 1 | -- Reverses project lat/long coordinates, as they were set in reversed order initially 2 | 3 | UPDATE 4 | civictechprojects_project 5 | SET 6 | project_location_coords = st_geometryfromtext('POINT('|| ST_Y(project_location_coords) ||' '|| ST_X(project_location_coords) ||')', 4326); 7 | -------------------------------------------------------------------------------- /civictechprojects/serializers.py: -------------------------------------------------------------------------------- 1 | from .models import Project 2 | from rest_framework import serializers 3 | 4 | 5 | class ProjectSerializer(serializers.HyperlinkedModelSerializer): 6 | class Meta: 7 | model = Project 8 | fields = ('project_name', 'project_url', 'project_description', 'project_tags') -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_AboutGroupDisplay.scss: -------------------------------------------------------------------------------- 1 | .AboutGroup-secondary-section { 2 | margin: 15px 0; 3 | padding: 15px; 4 | border: 1px solid $color-grey-frame-border; 5 | border-radius: 5px; 6 | } 7 | .AboutGroup-description { 8 | white-space: pre-wrap; 9 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_AlertHeader.scss: -------------------------------------------------------------------------------- 1 | .AlertHeader-root { 2 | display: flex; 3 | flex-direction: row; 4 | justify-content: flex-end; 5 | background-color: $color-orange; 6 | color: $color-text-dark; 7 | width: 100%; 8 | line-height: 1.2em; 9 | min-height: 34px; 10 | padding-top: 4px; 11 | } 12 | 13 | .AlertHeader-text { 14 | padding-left: 10px; 15 | width: auto; 16 | margin: 0.25rem auto; 17 | } 18 | 19 | .AlertHeader-text a { 20 | text-decoration: underline; 21 | color: $color-text-dark; 22 | } 23 | 24 | .AlertHeader-text p, 25 | i { 26 | text-align: center; 27 | } 28 | .AlertHeader-text p { 29 | margin: 0; 30 | } 31 | 32 | .AlertHeader-close { 33 | min-width: 30px; 34 | padding: 0 10px; 35 | cursor: pointer; 36 | } 37 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_AllowMarkdown.scss: -------------------------------------------------------------------------------- 1 | // markdown rendering (fix some issues with lists and white-space: pre-wrap, which we need to keep) 2 | .markdown-container ul, 3 | .markdown-container ol { 4 | white-space: initial; 5 | margin-top: -0.98rem; // may not be neccesary to undershoot 1rem, but certainly no more than 1rem here 6 | } 7 | 8 | .markdown-container ol:first-child, .markdown-container ul:first-child { 9 | padding-top: 1rem; 10 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ApproveGroupsSection.scss: -------------------------------------------------------------------------------- 1 | .ApproveGroups-row { 2 | max-width: 100%; 3 | } 4 | 5 | .ApproveGroups-row span { 6 | padding-right: 15px; 7 | } 8 | 9 | .ApproveGroups-logo img { 10 | max-width: 50px; 11 | } 12 | 13 | .ApproveGroups-button-reject { 14 | color: $color-red; 15 | border-color: $color-red; 16 | } 17 | 18 | .ApproveGroups-button-approve { 19 | color: $color-green; 20 | border-color: $color-green; 21 | } 22 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_BioModal.scss: -------------------------------------------------------------------------------- 1 | .bio-modal-name a { 2 | text-decoration: none; 3 | &:hover { 4 | text-decoration: underline; 5 | } 6 | } 7 | .bio-modal-title { 8 | color: $color-text-grey; 9 | } 10 | .bio-modal-about { 11 | color: $color-text-dark; 12 | } 13 | .bio-modal-root i { 14 | color: $color-text-grey; 15 | cursor: pointer; 16 | } 17 | .bio-modal-root > .modal-dialog { 18 | top: 0; 19 | } 20 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_CollapsibleMenuItem.scss: -------------------------------------------------------------------------------- 1 | .CollapsibleCategoryItem-root { 2 | cursor: pointer; 3 | margin-left: 10px; 4 | } 5 | 6 | .CollapsibleCategoryItem-root:last-child { 7 | margin-bottom: 10px; 8 | } 9 | 10 | .CollapsibleMenuItem { 11 | width: 100%; 12 | padding: 0px 10px; 13 | } 14 | 15 | .CollapsibleMenuItem:hover { 16 | color: $color-text-light; 17 | background-color: $color-green-dark; 18 | } 19 | 20 | .CollapsibleMenuItem > input[type="checkbox"] { 21 | margin-right: 5px; 22 | } 23 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_CollapsibleText.scss: -------------------------------------------------------------------------------- 1 | span.expand-toggle { 2 | cursor: pointer; 3 | color: $color-orange; 4 | } 5 | .expand-toggle:hover { 6 | text-decoration: underline; 7 | } 8 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ContactUs.scss: -------------------------------------------------------------------------------- 1 | //this file contains both ContactUsController and ContactForm component styles 2 | .contact-us-root { 3 | margin-top: 1rem; 4 | margin-bottom: 4rem; 5 | } 6 | 7 | .ContactForm-status-message { 8 | padding: 1rem 0.5rem; 9 | margin: 1rem 0; 10 | } 11 | 12 | .ContactForm-status-success { 13 | background: $color-background-success; 14 | } 15 | 16 | .ContactForm-status-error { 17 | background: $color-background-error; 18 | } 19 | 20 | .ContactForm-submit-btn { 21 | margin-top: 0.5rem; 22 | } 23 | .ContactForm-list { 24 | list-style-type: none; 25 | padding-left: 15px; 26 | input { 27 | display: inline-block; 28 | } 29 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_CreateForm.scss: -------------------------------------------------------------------------------- 1 | /* create event, create group flows */ 2 | 3 | .create-form-block { 4 | background-color: $color-background-light; 5 | box-shadow: -5px 5px 10px 1px rgba(0, 0, 0, 0.15); 6 | padding: 20px 10px; 7 | margin-bottom: 40px; 8 | 9 | .add-link { 10 | color: #0362cd; 11 | cursor: pointer; 12 | 13 | i { 14 | padding-right: 10px; 15 | } 16 | } 17 | } 18 | 19 | .form-offset { 20 | padding-left: 15px; 21 | } 22 | 23 | .create-selected-projects { 24 | margin-bottom: 1.25rem; 25 | } 26 | .create-selected-project-name { 27 | border-radius: 20px; 28 | background-color: #f3a73c; 29 | height: 40px; 30 | padding: 10px 30px; 31 | display: flex; 32 | margin: 0 10px 10px 0; 33 | justify-content: center; 34 | align-items: center; 35 | } 36 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_CreateProjectForm.scss: -------------------------------------------------------------------------------- 1 | .create-form.white-bg { 2 | background-color: $color-background-light; 3 | padding: 20px; 4 | border-bottom: 2px solid $color-grey-medium; 5 | border-top: 2px solid $color-grey-medium; 6 | } 7 | 8 | .create-form.grey-bg { 9 | background-color: $color-background-default; 10 | padding: 20px; 11 | } 12 | 13 | .create-project-saved-emblem { 14 | margin: auto 1rem auto auto; 15 | font-weight: bold; 16 | color: $color-orange; 17 | } 18 | .create-form-buttonrow { 19 | display: flex; 20 | justify-content: space-between; 21 | } 22 | 23 | .create-form-project-example { 24 | padding-left: 0.5rem; 25 | } 26 | .create-btn { 27 | min-width: 130px; 28 | } 29 | 30 | 31 | // quick fix to create's preview view having nested containers (thus, nested gutters) 32 | // TODO: fix this properly so preview is 100% accurate, removing these rules 33 | @include media-breakpoint-up(lg) { 34 | .create-form .Profile-primary-container { 35 | width: 550px; 36 | } 37 | } 38 | @include media-breakpoint-up(xl) { 39 | .create-form .Profile-primary-container { 40 | width: 690px; 41 | } 42 | } 43 | @include media-breakpoint-up(xxl) { 44 | .create-form .Profile-primary-container { 45 | width: 902px; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_DropDownMenuItem.scss: -------------------------------------------------------------------------------- 1 | .DropDownCategoryItem-root { 2 | cursor: pointer; 3 | padding-left: 15px; 4 | padding-right: 29px; 5 | } 6 | 7 | .DropDownCategoryItem-root.unselected:hover { 8 | color: $color-text-light; 9 | background-color: $color-green-dark; 10 | } 11 | 12 | .DropDownMenuItem-root { 13 | cursor: pointer; 14 | padding-left: 15px; 15 | padding-right: 29px; 16 | } 17 | 18 | .DropDownMenuItem-root.disabled, 19 | .DropDownCategoryItem-root.disabled { 20 | color: $color-grey-disabled; 21 | } 22 | 23 | .DropDownMenuItem-root:hover { 24 | color: $color-text-light; 25 | background-color: $color-green-dark; 26 | } 27 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_EmailVerifiedController.scss: -------------------------------------------------------------------------------- 1 | .EmailVerifiedController-root { 2 | min-height: 400px; 3 | } 4 | .EmailVerifiedController-logo { 5 | margin: 32px 0; 6 | } 7 | .EmailVerifiedController-greeting { 8 | margin: 0 0 32px 0; 9 | } 10 | 11 | .EmailVerifiedController-logo img { 12 | border-radius: 50%; 13 | width: 60px; 14 | height: 60px; 15 | } 16 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_FavoriteToggle.scss: -------------------------------------------------------------------------------- 1 | .favorite-toggle { 2 | height: 48px; 3 | width: 48px; 4 | display: flex; 5 | align-items: center; 6 | justify-content: center; 7 | 8 | i { 9 | font-size: 24px; 10 | } 11 | } 12 | 13 | .favorited { 14 | color: $color-favorite; 15 | } 16 | 17 | .unfavorited { 18 | color: $color-text-dark; 19 | } 20 | 21 | .favorite-toggle:hover .unfavorited { 22 | color: $color-favorite; 23 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_FileUploadList.scss: -------------------------------------------------------------------------------- 1 | .FileUploadList-item { 2 | display: flex; 3 | align-items: center; 4 | i { 5 | margin-left: 1rem; 6 | } 7 | a { 8 | max-width: calc(100% - 40px); 9 | display: inline-block; 10 | white-space: nowrap; 11 | overflow: hidden; 12 | text-overflow: ellipsis; 13 | } 14 | 15 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_FindProjectsController.scss: -------------------------------------------------------------------------------- 1 | .FindProjectsController-root .IntroText { 2 | padding-top: 1rem; 3 | font-weight: bold; 4 | } 5 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_FlashMessage.scss: -------------------------------------------------------------------------------- 1 | .FlashMessage-root { 2 | width: 90%; 3 | margin: auto; 4 | } 5 | 6 | .FlashMessage-root div { 7 | padding: 8px 16px; 8 | margin: 8px 0; 9 | } 10 | 11 | .FlashMessage-root .info { 12 | background-color: $color-background-info; 13 | } 14 | 15 | .FlashMessage-root .success { 16 | background-color: $color-green; 17 | } 18 | 19 | .FlashMessage-root .error { 20 | background-color: $color-background-error; 21 | } 22 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_Fonts.scss: -------------------------------------------------------------------------------- 1 | html, 2 | body { 3 | font-family: "Montserrat", sans-serif; 4 | } 5 | /*see also bootstrap override of $font-family-sans-serif */ 6 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_Forms.scss: -------------------------------------------------------------------------------- 1 | // Override bootstrap's error visibility 2 | .invalid-feedback.show-error { 3 | display: block 4 | } 5 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ImageCropUploadButton.scss: -------------------------------------------------------------------------------- 1 | .ImageCropUploadButton-cropper { 2 | position: relative; 3 | border: 1px solid black; 4 | border-radius: 10px; 5 | padding: 10px; 6 | 7 | .ImageCropUploadButton-buttonGroup { 8 | margin-top: 5px; 9 | 10 | input[type="button"]:not(:last-child) { 11 | margin-right: 10px; 12 | } 13 | } 14 | 15 | .FileSelectButton-dragFiles { 16 | color: #fff; 17 | font-weight: bold; 18 | } 19 | .ReactCrop__image { 20 | max-height: 500px; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_JoinConference.scss: -------------------------------------------------------------------------------- 1 | // for Join _ Video buttons with live usercounts, used on Event and ProjectEvent pages 2 | .JoinConference-livebutton { 3 | width: 100%; 4 | height: 40px; 5 | display: flex; 6 | justify-content: center; 7 | align-items: center; 8 | } 9 | // for the usercount specifically 10 | .JoinConference-usercount { 11 | background: $color-background-light; 12 | color: $color-text-dark; 13 | border-radius: 50%; 14 | font-weight: bold; 15 | min-height: 22px; // min-h and min-w so it has slightly better 3-digit usercount support 16 | min-width: 22px; 17 | align-self: flex-start; // vertical alig nment 18 | } 19 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_LinkList.scss: -------------------------------------------------------------------------------- 1 | //TODO: Get rid of this file if we don't end up needing it 2 | .LinkList .form-group { 3 | padding-left: 15px; 4 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_LiveEvent.scss: -------------------------------------------------------------------------------- 1 | .LiveEvent-root iframe { 2 | width: 100%; 3 | height: 100vh; 4 | min-height: 800px; 5 | } 6 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_LoadingFrame.scss: -------------------------------------------------------------------------------- 1 | .loading-frame { 2 | display: flex; 3 | justify-content: center; 4 | align-items: center; 5 | width: 100%; 6 | } 7 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_LoadingMessage.scss: -------------------------------------------------------------------------------- 1 | .loading-message { 2 | margin: 1rem; 3 | } 4 | 5 | .loading-message-text { 6 | display: inline; 7 | margin-left: 0.5rem; 8 | } 9 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_MyEvents.scss: -------------------------------------------------------------------------------- 1 | //keep page content off header and footer edges 2 | .MyEventsController-root { 3 | padding-top: 1rem; 4 | padding-bottom: 2rem; 5 | 6 | //keep subheaders within a section apart 7 | .EventCardContainer-section-header:nth-of-type(n + 2) { 8 | margin-top: 3rem; 9 | } 10 | } 11 | 12 | // keep multiple sections apart 13 | .MyEvents-eventsection:nth-of-type(n + 2) { 14 | margin-top: 3rem; 15 | } 16 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_MyProjectCard.scss: -------------------------------------------------------------------------------- 1 | .MyProjectCard-root { 2 | color: inherit; 3 | background-color: $color-background-light; 4 | border: solid 1px $color-grey-frame-border; 5 | margin: 20px auto; 6 | padding: 16px; 7 | } 8 | 9 | .MyProjectCard-header { 10 | color: $color-text-dark; 11 | font-style: italic; 12 | } 13 | 14 | .MyProjectCard-projectName { 15 | font-weight: bold; 16 | } 17 | 18 | .MyProjectCard-button { 19 | margin: 5px; 20 | } 21 | 22 | .MyProjectCard-table td { 23 | display: inline-block; 24 | width: 100%; 25 | } 26 | 27 | @include media-breakpoint-up(sm) { 28 | .MyProjectCard-table td { 29 | display: table-cell; 30 | width: 250px; 31 | } 32 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_MyProjectsController.scss: -------------------------------------------------------------------------------- 1 | .MyProjectsController-root { 2 | background: $color-background-default; 3 | h3 { 4 | margin-top: 24px; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_Newsletter.scss: -------------------------------------------------------------------------------- 1 | // custom styling for our newsletter signup box 2 | #mc_embed_signup { 3 | clear: left; 4 | } 5 | 6 | .mc_embed_hidden { 7 | position: absolute; 8 | left: -5000px; 9 | } 10 | 11 | #mc_embed_signup.button { 12 | display: inline; 13 | } 14 | 15 | .mc_display_none { 16 | display: none; 17 | } 18 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_PersonIcon.scss: -------------------------------------------------------------------------------- 1 | .PersonIcon { 2 | margin: 0px 0px 0px 5px; 3 | } 4 | 5 | .person-icon-container { 6 | height: 60px; 7 | width: 60px; 8 | margin: 0px 10px 0px 0px; 9 | float: left; 10 | cursor: pointer; 11 | svg { 12 | border-radius: 50%; 13 | color: $color-text-light; 14 | background: $color-text-grey; 15 | opacity: 0.5; 16 | height: 50px; 17 | width: 50px; 18 | padding-top: 5px; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_PositionList.scss: -------------------------------------------------------------------------------- 1 | .PositionList-entry { 2 | background-color: $color-background-light; 3 | box-shadow: 0 3px 5px rgba(0,0,0,0.2); 4 | padding: 5px; 5 | margin: 15px; 6 | max-width: 600px; 7 | min-height: 48px; 8 | align-items: center; 9 | display: flex; 10 | justify-content: space-between; 11 | cursor: grab; 12 | 13 | i { 14 | cursor: pointer; 15 | margin: auto 0; 16 | } 17 | i:hover { 18 | color:$color-orange; 19 | } 20 | } 21 | 22 | .PositionList-entry.dim { 23 | color:$color-grey-disabled; 24 | } 25 | 26 | .PositionList-entry.grabbed { 27 | cursor: grabbing; 28 | background-color: $color-grey-medium; 29 | } 30 | 31 | i.grip { 32 | color:$color-grey-disabled; 33 | padding-right: 5px; 34 | } 35 | i.grip:hover { 36 | color:$color-grey-disabled; 37 | } 38 | 39 | .left-side i { 40 | padding-right: 8px; 41 | } 42 | 43 | .right-side { 44 | display: flex; 45 | justify-content: space-between; 46 | width: 80px; 47 | } 48 | 49 | .orderInstructions { 50 | padding: 20px 0; 51 | p { 52 | margin-bottom: 0px; 53 | } 54 | p.dragRoleInstructions { 55 | font-style: italic; 56 | } 57 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_Privacy.scss: -------------------------------------------------------------------------------- 1 | .Privacy-root { 2 | h1 { 3 | padding: 1rem 0; 4 | } 5 | ol > li { 6 | padding: 1rem; // section separators 7 | } 8 | li > ul { 9 | margin-top: 0.5rem; // vertical spacing at the start of nested lists 10 | } 11 | ul { 12 | list-style-type: disc; // nested list defaults to circle, so override 13 | } 14 | ul > li { 15 | padding: 0.125rem 0; // spacing within each section's list 16 | } 17 | } 18 | // for narrow device width and chrome browser there's some potential overflow issues: 19 | @include media-breakpoint-only(xs) { 20 | ol, 21 | ul { 22 | padding-inline-start: 20px; // nested lists with nested 40px default on narrow devices is a real squeeze 23 | } 24 | li a { 25 | overflow-wrap: break-word; // just in case the contact link doesn't wrap, which seems to be chrome-only 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ProjectCardContainer.scss: -------------------------------------------------------------------------------- 1 | .ProjectCardContainer-header { 2 | margin: 15px 15px 8px 15px; 3 | width: 100%; 4 | } 5 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ProjectCardsContainer.scss: -------------------------------------------------------------------------------- 1 | .page_selection_footer { 2 | display: flex; 3 | justify-content: space-evenly; 4 | margin: 15px 0; 5 | } 6 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ProjectProfileSearch.scss: -------------------------------------------------------------------------------- 1 | .ProjectProfileSearch-root { 2 | button.reset-search-button { 3 | max-width: 150px; 4 | } 5 | .ProjectTagContainer-root { 6 | border: 0; 7 | padding: 0; 8 | margin: 8px; 9 | } 10 | .preview-panel { 11 | border: 1px solid $color-grey-frame-border; 12 | border-radius: 8px; 13 | } 14 | .preview-panel-toggle { 15 | padding: 8px 16px; 16 | cursor: pointer; // hint that this is interactable 17 | } 18 | .ProjectFilterContainer-list-item { 19 | padding-left: 1rem; 20 | } 21 | } 22 | 23 | h3.ProjectProfileSearch-sectiontitle { 24 | margin-top: auto; 25 | } 26 | 27 | .ProjectProfileSearch-sort h4 { 28 | margin: auto 8px auto 0; 29 | flex-shrink: 0; // ensures title will not wrap onto two lines 30 | } 31 | 32 | @include media-breakpoint-up(lg) { 33 | .ProjectProfileSearch-root { 34 | .ProjectFilterContainer-category-header, 35 | .ProjectFilterContainer-subcategory-header, 36 | .ProjectFilterContainer-filter-list, 37 | .favorite-filter { 38 | margin: 0 2rem; 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ProjectSearchBar.scss: -------------------------------------------------------------------------------- 1 | .ProjectSearchBar-root { 2 | border: solid 1px $color-grey-frame-border; 3 | border-radius: 5px; 4 | height: 38px; /* 38 + 1px top and bottom border = 40 */ 5 | width: 100%; 6 | display: flex; 7 | } 8 | 9 | .ProjectSearchBar-root > i { 10 | margin-left: 10px; 11 | margin-top: 10px; 12 | flex-grow: 0; 13 | } 14 | 15 | .ProjectSearchBar-input { 16 | border: 0; 17 | outline-width: 0; 18 | margin-left: 10px; 19 | height: 100%; 20 | flex-grow: 1; 21 | background: inherit; 22 | } 23 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ProjectSearchSort.scss: -------------------------------------------------------------------------------- 1 | .ProjectSearchSort-container { 2 | margin-left: -15px; /*margin/padding values to extend background/border to cross the gutter from grid */ 3 | margin-right: -15px; 4 | padding: 0 15px 15px 15px; 5 | background: $color-background-light; 6 | } 7 | 8 | .ProjectSearchSort-sortform { 9 | padding: 0; 10 | border: none; 11 | background: inherit; 12 | background-color: inherit; 13 | } 14 | 15 | /*this should be controlled by react-select v2's style object in the future */ 16 | .ProjectSearchSort__indicator-separator { 17 | display: none; 18 | } 19 | 20 | @include media-breakpoint-up(lg) { 21 | .ProjectSearchSort-sortform { 22 | max-width: 22%; 23 | margin-left: 0.5rem; 24 | } 25 | .ProjectSearchSort-container { 26 | padding-bottom: 0; 27 | display: flex; 28 | height: 71px; /*needs to match height of .ProjectFilterContainer-reset -border (so -1px) */ 29 | align-items: center; 30 | justify-content: space-between; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ProjectTag.scss: -------------------------------------------------------------------------------- 1 | .ProjectTag-root { 2 | background-color: $color-orange; 3 | border-radius: 30px; /*can't use 50% because item isn't a square, so just use any number > 50% element height */ 4 | color: $color-text-dark; 5 | display: inline-block; 6 | margin-bottom: 10px; /*provides spacing in case active tags wrap onto two rows */ 7 | margin-right: 10px; 8 | padding: 6px 10px 5px 15px; 9 | } 10 | 11 | .ProjectTag-closeButton { 12 | align-items: center; 13 | background-color: $color-orange-dark; 14 | border-radius: 50%; 15 | cursor: pointer; 16 | display: inline-flex; 17 | height: 25px; 18 | justify-content: center; 19 | margin-left: 10px; 20 | width: 25px; 21 | } 22 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ProjectTagContainer.scss: -------------------------------------------------------------------------------- 1 | .ProjectTagContainer-root { 2 | clear: both; 3 | background: $color-background-light; 4 | margin-left: -15px; /*the margin/padding values are to extend border over the gutter from the bootstrap grid */ 5 | padding-left: 15px; 6 | margin-right: -15px; 7 | padding-right: 10px; /* this is an experiment to see if tags will fit on one line cleanly; if it fails set it to 15px */ 8 | border-bottom: 1px solid $color-grey-medium; 9 | } 10 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ResetSearchButton.scss: -------------------------------------------------------------------------------- 1 | button.reset-search-button { 2 | max-width: 80%; 3 | height: 40px; 4 | } 5 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_SectionLink.scss: -------------------------------------------------------------------------------- 1 | .SectionLink-root { 2 | cursor: pointer; 3 | display: inline-block; 4 | font-weight: bold; 5 | margin: 5px 8px 0px 8px; 6 | padding-bottom: 0px; 7 | align-self: flex-end; 8 | 9 | &:hover { 10 | h3, 11 | h3 > a { 12 | color: $color-orange; 13 | } 14 | } 15 | } 16 | 17 | .SectionLink-root h3 { 18 | border-bottom: 3px solid transparent; 19 | color: $color-text-grey; 20 | padding-bottom: 14px; 21 | margin: 0px 5px; 22 | transition: 300ms; 23 | } 24 | 25 | .SectionLink-active h3 { 26 | border-bottom: $color-orange 3px solid; 27 | color: $color-orange; 28 | padding-bottom: 14px; 29 | margin: 0px 5px; 30 | box-sizing: border-box; 31 | } 32 | 33 | @include media-breakpoint-up(md) { 34 | // .SectionLink-root { 35 | // margin: 13px 4%; 36 | // padding-bottom: 8px; 37 | // } 38 | } 39 | 40 | @include media-breakpoint-between(sm, md) { 41 | // .SectionLink-root { 42 | // margin: 10px 8px 0px 8px; 43 | // } 44 | } 45 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_SignUpController.scss: -------------------------------------------------------------------------------- 1 | .SignUpController-socialSection { 2 | display: block; 3 | margin-top: 100px; 4 | width: 100%; 5 | } 6 | 7 | .LogInController-root input + span { 8 | padding-left: 10px; 9 | } 10 | 11 | .Terms-body li { 12 | padding-bottom: 5px; 13 | } 14 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_SignedUpController.scss: -------------------------------------------------------------------------------- 1 | .SignedUpController-root { 2 | min-height: 400px; 3 | } 4 | .SignedUpController-logo { 5 | margin: 32px 0; 6 | } 7 | .SignedUpController-greeting { 8 | margin: 0 0 32px 0; 9 | } 10 | 11 | .SignedUpController-logo img { 12 | border-radius: 50%; 13 | width: 60px; 14 | height: 60px; 15 | } 16 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_StepIndicatorBars.scss: -------------------------------------------------------------------------------- 1 | .step-bars { 2 | display: flex; 3 | flex-direction: row; 4 | max-width: 800px; 5 | padding: 10px; 6 | } 7 | 8 | .step-bar { 9 | background: $color-grey-medium; 10 | border-radius: 25px; 11 | width: 75px; 12 | height: 7px; 13 | margin: 10px; 14 | } 15 | 16 | .step-bar.selected { 17 | background: $color-orange; 18 | } 19 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_Terms.scss: -------------------------------------------------------------------------------- 1 | .Terms-root { 2 | padding: 1rem 0 2rem 0; 3 | scroll-behavior: smooth; 4 | } 5 | 6 | .Terms-section { 7 | position: relative; // a downside to is it requires a relative positioned parent element 8 | padding: 2rem 0; 9 | } 10 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_ThankYouController.scss: -------------------------------------------------------------------------------- 1 | .ThankYou-leftImage img { 2 | height: 100%; 3 | width: 100%; 4 | object-fit: cover; 5 | } 6 | .ThankYou-rightColumn h2 { 7 | margin: 1.5rem 0; 8 | } 9 | .ThankYou-rightColumn p { 10 | padding-bottom: 2rem; 11 | } 12 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_Video.scss: -------------------------------------------------------------------------------- 1 | .youtube-video-container { 2 | position: relative; 3 | overflow: hidden; 4 | width: 95%; 5 | margin: 0 auto; 6 | max-height: calc(100vh - 160px); 7 | } 8 | 9 | .youtube-video-container::after { 10 | display: block; 11 | content: ""; 12 | padding-top: 56.25%; 13 | } 14 | 15 | .youtube-video-container iframe { 16 | position: absolute; 17 | top: 0; 18 | left: 0; 19 | width: 100%; 20 | height: 100%; 21 | } -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_VolunteerCard.scss: -------------------------------------------------------------------------------- 1 | .VolunteerCard-root { 2 | color: inherit; 3 | clear: both; 4 | height: 101px; 5 | padding-bottom: 20px; 6 | } 7 | 8 | .VolunteerCard-img { 9 | float: left; 10 | margin-right: 10px; 11 | object-fit: contain; 12 | background-color: $color-grey-medium; 13 | width: 80px; 14 | height: 81px; 15 | border: none; 16 | } 17 | 18 | .VolunteerCard-volunteerName { 19 | font-weight: bold; 20 | padding-top: 10px; 21 | } 22 | 23 | .VolunteerCard-volunteerRole { 24 | font-weight: normal; 25 | } 26 | 27 | div.VolunteerCard-dropdownButton { 28 | display: inline; 29 | float: right; 30 | } 31 | .VolunteerCard-dropdownButton .btn-link { 32 | color: $color-text-grey; 33 | } 34 | .VolunteerCard-root a.dropdown-item { 35 | /* overrides orange link text for the project owner's manage team member dropdown menu */ 36 | color: inherit; 37 | } 38 | /* rotate thumbtack 45 degrees */ 39 | .VolunteerCard-dropdownButton .fa-thumbtack { 40 | -webkit-transform: rotate(45deg); 41 | -moz-transform: rotate(45deg); 42 | -ms-transform: rotate(45deg); 43 | -o-transform: rotate(45deg); 44 | transform: rotate(45deg); 45 | } 46 | -------------------------------------------------------------------------------- /civictechprojects/static/css/partials/_base.scss: -------------------------------------------------------------------------------- 1 | input { 2 | background-color: $color-background-default; 3 | } 4 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_close.scss: -------------------------------------------------------------------------------- 1 | .close { 2 | float: right; 3 | @include font-size($close-font-size); 4 | font-weight: $close-font-weight; 5 | line-height: 1; 6 | color: $close-color; 7 | text-shadow: $close-text-shadow; 8 | opacity: .5; 9 | 10 | // Override 's hover style 11 | @include hover { 12 | color: $close-color; 13 | text-decoration: none; 14 | } 15 | 16 | &:not(:disabled):not(.disabled) { 17 | @include hover-focus { 18 | opacity: .75; 19 | } 20 | } 21 | } 22 | 23 | // Additional properties for button version 24 | // iOS requires the button element instead of an anchor tag. 25 | // If you want the anchor version, it requires `href="#"`. 26 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile 27 | 28 | // stylelint-disable-next-line selector-no-qualifying-type 29 | button.close { 30 | padding: 0; 31 | background-color: transparent; 32 | border: 0; 33 | appearance: none; 34 | } 35 | 36 | // Future-proof disabling of clicks on `` elements 37 | 38 | // stylelint-disable-next-line selector-no-qualifying-type 39 | a.close.disabled { 40 | pointer-events: none; 41 | } 42 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_code.scss: -------------------------------------------------------------------------------- 1 | // Inline code 2 | code { 3 | @include font-size($code-font-size); 4 | color: $code-color; 5 | word-break: break-word; 6 | 7 | // Streamline the style when inside anchors to avoid broken underline and more 8 | a > & { 9 | color: inherit; 10 | } 11 | } 12 | 13 | // User input typically entered via keyboard 14 | kbd { 15 | padding: $kbd-padding-y $kbd-padding-x; 16 | @include font-size($kbd-font-size); 17 | color: $kbd-color; 18 | background-color: $kbd-bg; 19 | @include border-radius($border-radius-sm); 20 | @include box-shadow($kbd-box-shadow); 21 | 22 | kbd { 23 | padding: 0; 24 | @include font-size(100%); 25 | font-weight: $nested-kbd-font-weight; 26 | @include box-shadow(none); 27 | } 28 | } 29 | 30 | // Blocks of code 31 | pre { 32 | display: block; 33 | @include font-size($code-font-size); 34 | color: $pre-color; 35 | 36 | // Account for some code outputs that place code tags in pre tags 37 | code { 38 | @include font-size(inherit); 39 | color: inherit; 40 | word-break: normal; 41 | } 42 | } 43 | 44 | // Enable scrollable blocks of code 45 | .pre-scrollable { 46 | max-height: $pre-scrollable-max-height; 47 | overflow-y: scroll; 48 | } 49 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_jumbotron.scss: -------------------------------------------------------------------------------- 1 | .jumbotron { 2 | padding: $jumbotron-padding ($jumbotron-padding / 2); 3 | margin-bottom: $jumbotron-padding; 4 | color: $jumbotron-color; 5 | background-color: $jumbotron-bg; 6 | @include border-radius($border-radius-lg); 7 | 8 | @include media-breakpoint-up(sm) { 9 | padding: ($jumbotron-padding * 2) $jumbotron-padding; 10 | } 11 | } 12 | 13 | .jumbotron-fluid { 14 | padding-right: 0; 15 | padding-left: 0; 16 | @include border-radius(0); 17 | } 18 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_media.scss: -------------------------------------------------------------------------------- 1 | .media { 2 | display: flex; 3 | align-items: flex-start; 4 | } 5 | 6 | .media-body { 7 | flex: 1; 8 | } 9 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_root.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | // Custom variable values only support SassScript inside `#{}`. 3 | @each $color, $value in $colors { 4 | --#{$color}: #{$value}; 5 | } 6 | 7 | @each $color, $value in $theme-colors { 8 | --#{$color}: #{$value}; 9 | } 10 | 11 | @each $bp, $value in $grid-breakpoints { 12 | --breakpoint-#{$bp}: #{$value}; 13 | } 14 | 15 | // Use `inspect` for lists so that quoted items keep the quotes. 16 | // See https://github.com/sass/sass/issues/2383#issuecomment-336349172 17 | --font-family-sans-serif: #{inspect($font-family-sans-serif)}; 18 | --font-family-monospace: #{inspect($font-family-monospace)}; 19 | } 20 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_toasts.scss: -------------------------------------------------------------------------------- 1 | .toast { 2 | max-width: $toast-max-width; 3 | overflow: hidden; // cheap rounded corners on nested items 4 | @include font-size($toast-font-size); 5 | color: $toast-color; 6 | background-color: $toast-background-color; 7 | background-clip: padding-box; 8 | border: $toast-border-width solid $toast-border-color; 9 | box-shadow: $toast-box-shadow; 10 | backdrop-filter: blur(10px); 11 | opacity: 0; 12 | @include border-radius($toast-border-radius); 13 | 14 | &:not(:last-child) { 15 | margin-bottom: $toast-padding-x; 16 | } 17 | 18 | &.showing { 19 | opacity: 1; 20 | } 21 | 22 | &.show { 23 | display: block; 24 | opacity: 1; 25 | } 26 | 27 | &.hide { 28 | display: none; 29 | } 30 | } 31 | 32 | .toast-header { 33 | display: flex; 34 | align-items: center; 35 | padding: $toast-padding-y $toast-padding-x; 36 | color: $toast-header-color; 37 | background-color: $toast-header-background-color; 38 | background-clip: padding-box; 39 | border-bottom: $toast-border-width solid $toast-header-border-color; 40 | } 41 | 42 | .toast-body { 43 | padding: $toast-padding-x; // apply to both vertical and horizontal 44 | } 45 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_transitions.scss: -------------------------------------------------------------------------------- 1 | .fade { 2 | @include transition($transition-fade); 3 | 4 | &:not(.show) { 5 | opacity: 0; 6 | } 7 | } 8 | 9 | .collapse { 10 | &:not(.show) { 11 | display: none; 12 | } 13 | } 14 | 15 | .collapsing { 16 | position: relative; 17 | height: 0; 18 | overflow: hidden; 19 | @include transition($transition-collapse); 20 | } 21 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/_utilities.scss: -------------------------------------------------------------------------------- 1 | @import "utilities/align"; 2 | @import "utilities/background"; 3 | @import "utilities/borders"; 4 | @import "utilities/clearfix"; 5 | @import "utilities/display"; 6 | @import "utilities/embed"; 7 | @import "utilities/flex"; 8 | @import "utilities/float"; 9 | @import "utilities/overflow"; 10 | @import "utilities/position"; 11 | @import "utilities/screenreaders"; 12 | @import "utilities/shadows"; 13 | @import "utilities/sizing"; 14 | @import "utilities/stretched-link"; 15 | @import "utilities/spacing"; 16 | @import "utilities/text"; 17 | @import "utilities/visibility"; 18 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/bootstrap-grid.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Grid v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors 4 | * Copyright 2011-2019 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | html { 9 | box-sizing: border-box; 10 | -ms-overflow-style: scrollbar; 11 | } 12 | 13 | *, 14 | *::before, 15 | *::after { 16 | box-sizing: inherit; 17 | } 18 | 19 | @import "functions"; 20 | @import "variables"; 21 | 22 | @import "mixins/breakpoints"; 23 | @import "mixins/grid-framework"; 24 | @import "mixins/grid"; 25 | 26 | @import "grid"; 27 | @import "utilities/display"; 28 | @import "utilities/flex"; 29 | @import "utilities/spacing"; 30 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/bootstrap-reboot.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap Reboot v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors 4 | * Copyright 2011-2019 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | * Forked from Normalize.css, licensed MIT (https://github.com/necolas/normalize.css/blob/master/LICENSE.md) 7 | */ 8 | 9 | @import "functions"; 10 | @import "variables"; 11 | @import "mixins"; 12 | @import "reboot"; 13 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/bootstrap.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Bootstrap v4.3.1 (https://getbootstrap.com/) 3 | * Copyright 2011-2019 The Bootstrap Authors 4 | * Copyright 2011-2019 Twitter, Inc. 5 | * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) 6 | */ 7 | 8 | @import "functions"; 9 | @import "variables"; 10 | @import "mixins"; 11 | @import "root"; 12 | @import "reboot"; 13 | @import "type"; 14 | @import "images"; 15 | @import "code"; 16 | @import "grid"; 17 | @import "tables"; 18 | @import "forms"; 19 | @import "buttons"; 20 | @import "transitions"; 21 | @import "dropdown"; 22 | @import "button-group"; 23 | @import "input-group"; 24 | @import "custom-forms"; 25 | @import "nav"; 26 | @import "navbar"; 27 | @import "card"; 28 | @import "breadcrumb"; 29 | @import "pagination"; 30 | @import "badge"; 31 | @import "jumbotron"; 32 | @import "alert"; 33 | @import "progress"; 34 | @import "media"; 35 | @import "list-group"; 36 | @import "close"; 37 | @import "toasts"; 38 | @import "modal"; 39 | @import "tooltip"; 40 | @import "popover"; 41 | @import "carousel"; 42 | @import "spinners"; 43 | @import "utilities"; 44 | @import "print"; 45 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_alert.scss: -------------------------------------------------------------------------------- 1 | @mixin alert-variant($background, $border, $color) { 2 | color: $color; 3 | @include gradient-bg($background); 4 | border-color: $border; 5 | 6 | hr { 7 | border-top-color: darken($border, 5%); 8 | } 9 | 10 | .alert-link { 11 | color: darken($color, 10%); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_background-variant.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Contextual backgrounds 4 | 5 | @mixin bg-variant($parent, $color) { 6 | #{$parent} { 7 | background-color: $color !important; 8 | } 9 | a#{$parent}, 10 | button#{$parent} { 11 | @include hover-focus { 12 | background-color: darken($color, 10%) !important; 13 | } 14 | } 15 | } 16 | 17 | @mixin bg-gradient-variant($parent, $color) { 18 | #{$parent} { 19 | background: $color linear-gradient(180deg, mix($body-bg, $color, 15%), $color) repeat-x !important; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_badge.scss: -------------------------------------------------------------------------------- 1 | @mixin badge-variant($bg) { 2 | color: color-yiq($bg); 3 | background-color: $bg; 4 | 5 | @at-root a#{&} { 6 | @include hover-focus { 7 | color: color-yiq($bg); 8 | background-color: darken($bg, 10%); 9 | } 10 | 11 | &:focus, 12 | &.focus { 13 | outline: 0; 14 | box-shadow: 0 0 0 $badge-focus-width rgba($bg, .5); 15 | } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_box-shadow.scss: -------------------------------------------------------------------------------- 1 | @mixin box-shadow($shadow...) { 2 | @if $enable-shadows { 3 | $result: (); 4 | 5 | @if (length($shadow) == 1) { 6 | // We can pass `@include box-shadow(none);` 7 | $result: $shadow; 8 | } @else { 9 | // Filter to avoid invalid properties for example `box-shadow: none, 1px 1px black;` 10 | @for $i from 1 through length($shadow) { 11 | @if nth($shadow, $i) != "none" { 12 | $result: append($result, nth($shadow, $i), "comma"); 13 | } 14 | } 15 | } 16 | @if (length($result) > 0) { 17 | box-shadow: $result; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_clearfix.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix() { 2 | &::after { 3 | display: block; 4 | clear: both; 5 | content: ""; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_deprecate.scss: -------------------------------------------------------------------------------- 1 | // Deprecate mixin 2 | // 3 | // This mixin can be used to deprecate mixins or functions. 4 | // `$enable-deprecation-messages` is a global variable, `$ignore-warning` is a variable that can be passed to 5 | // some deprecated mixins to suppress the warning (for example if the mixin is still be used in the current version of Bootstrap) 6 | @mixin deprecate($name, $deprecate-version, $remove-version, $ignore-warning: false) { 7 | @if ($enable-deprecation-messages != false and $ignore-warning != true) { 8 | @warn "#{$name} has been deprecated as of #{$deprecate-version}. It will be removed entirely in #{$remove-version}."; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_float.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | @mixin float-left { 4 | float: left !important; 5 | @include deprecate("The `float-left` mixin", "v4.3.0", "v5"); 6 | } 7 | @mixin float-right { 8 | float: right !important; 9 | @include deprecate("The `float-right` mixin", "v4.3.0", "v5"); 10 | } 11 | @mixin float-none { 12 | float: none !important; 13 | @include deprecate("The `float-none` mixin", "v4.3.0", "v5"); 14 | } 15 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_hover.scss: -------------------------------------------------------------------------------- 1 | // Hover mixin and `$enable-hover-media-query` are deprecated. 2 | // 3 | // Originally added during our alphas and maintained during betas, this mixin was 4 | // designed to prevent `:hover` stickiness on iOS-an issue where hover styles 5 | // would persist after initial touch. 6 | // 7 | // For backward compatibility, we've kept these mixins and updated them to 8 | // always return their regular pseudo-classes instead of a shimmed media query. 9 | // 10 | // Issue: https://github.com/twbs/bootstrap/issues/25195 11 | 12 | @mixin hover { 13 | &:hover { @content; } 14 | } 15 | 16 | @mixin hover-focus { 17 | &:hover, 18 | &:focus { 19 | @content; 20 | } 21 | } 22 | 23 | @mixin plain-hover-focus { 24 | &, 25 | &:hover, 26 | &:focus { 27 | @content; 28 | } 29 | } 30 | 31 | @mixin hover-focus-active { 32 | &:hover, 33 | &:focus, 34 | &:active { 35 | @content; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_list-group.scss: -------------------------------------------------------------------------------- 1 | // List Groups 2 | 3 | @mixin list-group-item-variant($state, $background, $color) { 4 | .list-group-item-#{$state} { 5 | color: $color; 6 | background-color: $background; 7 | 8 | &.list-group-item-action { 9 | @include hover-focus { 10 | color: $color; 11 | background-color: darken($background, 5%); 12 | } 13 | 14 | &.active { 15 | color: $white; 16 | background-color: $color; 17 | border-color: $color; 18 | } 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_lists.scss: -------------------------------------------------------------------------------- 1 | // Lists 2 | 3 | // Unstyled keeps list items block level, just removes default browser padding and list-style 4 | @mixin list-unstyled { 5 | padding-left: 0; 6 | list-style: none; 7 | } 8 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_nav-divider.scss: -------------------------------------------------------------------------------- 1 | // Horizontal dividers 2 | // 3 | // Dividers (basically an hr) within dropdowns and nav lists 4 | 5 | @mixin nav-divider($color: $nav-divider-color, $margin-y: $nav-divider-margin-y) { 6 | height: 0; 7 | margin: $margin-y 0; 8 | overflow: hidden; 9 | border-top: 1px solid $color; 10 | } 11 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_pagination.scss: -------------------------------------------------------------------------------- 1 | // Pagination 2 | 3 | @mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) { 4 | .page-link { 5 | padding: $padding-y $padding-x; 6 | @include font-size($font-size); 7 | line-height: $line-height; 8 | } 9 | 10 | .page-item { 11 | &:first-child { 12 | .page-link { 13 | @include border-left-radius($border-radius); 14 | } 15 | } 16 | &:last-child { 17 | .page-link { 18 | @include border-right-radius($border-radius); 19 | } 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_reset-text.scss: -------------------------------------------------------------------------------- 1 | @mixin reset-text { 2 | font-family: $font-family-base; 3 | // We deliberately do NOT reset font-size or word-wrap. 4 | font-style: normal; 5 | font-weight: $font-weight-normal; 6 | line-height: $line-height-base; 7 | text-align: left; // Fallback for where `start` is not supported 8 | text-align: start; 9 | text-decoration: none; 10 | text-shadow: none; 11 | text-transform: none; 12 | letter-spacing: normal; 13 | word-break: normal; 14 | word-spacing: normal; 15 | white-space: normal; 16 | line-break: auto; 17 | } 18 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_resize.scss: -------------------------------------------------------------------------------- 1 | // Resize anything 2 | 3 | @mixin resizable($direction) { 4 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible` 5 | resize: $direction; // Options: horizontal, vertical, both 6 | } 7 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Only display content to screen readers 2 | // 3 | // See: https://a11yproject.com/posts/how-to-hide-content/ 4 | // See: https://hugogiraudel.com/2016/10/13/css-hide-and-seek/ 5 | 6 | @mixin sr-only { 7 | position: absolute; 8 | width: 1px; 9 | height: 1px; 10 | padding: 0; 11 | overflow: hidden; 12 | clip: rect(0, 0, 0, 0); 13 | white-space: nowrap; 14 | border: 0; 15 | } 16 | 17 | // Use in conjunction with .sr-only to only display content when it's focused. 18 | // 19 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 20 | // 21 | // Credit: HTML5 Boilerplate 22 | 23 | @mixin sr-only-focusable { 24 | &:active, 25 | &:focus { 26 | position: static; 27 | width: auto; 28 | height: auto; 29 | overflow: visible; 30 | clip: auto; 31 | white-space: normal; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_size.scss: -------------------------------------------------------------------------------- 1 | // Sizing shortcuts 2 | 3 | @mixin size($width, $height: $width) { 4 | width: $width; 5 | height: $height; 6 | @include deprecate("`size()`", "v4.3.0", "v5"); 7 | } 8 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_table-row.scss: -------------------------------------------------------------------------------- 1 | // Tables 2 | 3 | @mixin table-row-variant($state, $background, $border: null) { 4 | // Exact selectors below required to override `.table-striped` and prevent 5 | // inheritance to nested tables. 6 | .table-#{$state} { 7 | &, 8 | > th, 9 | > td { 10 | background-color: $background; 11 | } 12 | 13 | @if $border != null { 14 | th, 15 | td, 16 | thead th, 17 | tbody + tbody { 18 | border-color: $border; 19 | } 20 | } 21 | } 22 | 23 | // Hover states for `.table-hover` 24 | // Note: this is not available for cells or rows within `thead` or `tfoot`. 25 | .table-hover { 26 | $hover-background: darken($background, 5%); 27 | 28 | .table-#{$state} { 29 | @include hover { 30 | background-color: $hover-background; 31 | 32 | > td, 33 | > th { 34 | background-color: $hover-background; 35 | } 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_text-emphasis.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Typography 4 | 5 | @mixin text-emphasis-variant($parent, $color) { 6 | #{$parent} { 7 | color: $color !important; 8 | } 9 | @if $emphasized-link-hover-darken-percentage != 0 { 10 | a#{$parent} { 11 | @include hover-focus { 12 | color: darken($color, $emphasized-link-hover-darken-percentage) !important; 13 | } 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_text-hide.scss: -------------------------------------------------------------------------------- 1 | // CSS image replacement 2 | @mixin text-hide($ignore-warning: false) { 3 | // stylelint-disable-next-line font-family-no-missing-generic-family-keyword 4 | font: 0/0 a; 5 | color: transparent; 6 | text-shadow: none; 7 | background-color: transparent; 8 | border: 0; 9 | 10 | @include deprecate("`text-hide()`", "v4.1.0", "v5", $ignore-warning); 11 | } 12 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_text-truncate.scss: -------------------------------------------------------------------------------- 1 | // Text truncate 2 | // Requires inline-block or block for proper styling 3 | 4 | @mixin text-truncate() { 5 | overflow: hidden; 6 | text-overflow: ellipsis; 7 | white-space: nowrap; 8 | } 9 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_transition.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable property-blacklist 2 | @mixin transition($transition...) { 3 | @if $enable-transitions { 4 | @if length($transition) == 0 { 5 | transition: $transition-base; 6 | } @else { 7 | transition: $transition; 8 | } 9 | } 10 | 11 | @if $enable-prefers-reduced-motion-media-query { 12 | @media (prefers-reduced-motion: reduce) { 13 | transition: none; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/mixins/_visibility.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Visibility 4 | 5 | @mixin invisible($visibility) { 6 | visibility: $visibility !important; 7 | @include deprecate("`invisible()`", "v4.3.0", "v5"); 8 | } 9 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_align.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | .align-baseline { vertical-align: baseline !important; } // Browser default 4 | .align-top { vertical-align: top !important; } 5 | .align-middle { vertical-align: middle !important; } 6 | .align-bottom { vertical-align: bottom !important; } 7 | .align-text-bottom { vertical-align: text-bottom !important; } 8 | .align-text-top { vertical-align: text-top !important; } 9 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_background.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | @each $color, $value in $theme-colors { 4 | @include bg-variant(".bg-#{$color}", $value); 5 | } 6 | 7 | @if $enable-gradients { 8 | @each $color, $value in $theme-colors { 9 | @include bg-gradient-variant(".bg-gradient-#{$color}", $value); 10 | } 11 | } 12 | 13 | .bg-white { 14 | background-color: $white !important; 15 | } 16 | 17 | .bg-transparent { 18 | background-color: transparent !important; 19 | } 20 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_clearfix.scss: -------------------------------------------------------------------------------- 1 | .clearfix { 2 | @include clearfix(); 3 | } 4 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_display.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // 4 | // Utilities for common `display` values 5 | // 6 | 7 | @each $breakpoint in map-keys($grid-breakpoints) { 8 | @include media-breakpoint-up($breakpoint) { 9 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 10 | 11 | @each $value in $displays { 12 | .d#{$infix}-#{$value} { display: $value !important; } 13 | } 14 | } 15 | } 16 | 17 | 18 | // 19 | // Utilities for toggling `display` in print 20 | // 21 | 22 | @media print { 23 | @each $value in $displays { 24 | .d-print-#{$value} { display: $value !important; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_embed.scss: -------------------------------------------------------------------------------- 1 | // Credit: Nicolas Gallagher and SUIT CSS. 2 | 3 | .embed-responsive { 4 | position: relative; 5 | display: block; 6 | width: 100%; 7 | padding: 0; 8 | overflow: hidden; 9 | 10 | &::before { 11 | display: block; 12 | content: ""; 13 | } 14 | 15 | .embed-responsive-item, 16 | iframe, 17 | embed, 18 | object, 19 | video { 20 | position: absolute; 21 | top: 0; 22 | bottom: 0; 23 | left: 0; 24 | width: 100%; 25 | height: 100%; 26 | border: 0; 27 | } 28 | } 29 | 30 | @each $embed-responsive-aspect-ratio in $embed-responsive-aspect-ratios { 31 | $embed-responsive-aspect-ratio-x: nth($embed-responsive-aspect-ratio, 1); 32 | $embed-responsive-aspect-ratio-y: nth($embed-responsive-aspect-ratio, 2); 33 | 34 | .embed-responsive-#{$embed-responsive-aspect-ratio-x}by#{$embed-responsive-aspect-ratio-y} { 35 | &::before { 36 | padding-top: percentage($embed-responsive-aspect-ratio-y / $embed-responsive-aspect-ratio-x); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_float.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | @each $breakpoint in map-keys($grid-breakpoints) { 4 | @include media-breakpoint-up($breakpoint) { 5 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints); 6 | 7 | .float#{$infix}-left { float: left !important; } 8 | .float#{$infix}-right { float: right !important; } 9 | .float#{$infix}-none { float: none !important; } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_overflow.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | @each $value in $overflows { 4 | .overflow-#{$value} { overflow: $value !important; } 5 | } 6 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_position.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Common values 4 | @each $position in $positions { 5 | .position-#{$position} { position: $position !important; } 6 | } 7 | 8 | // Shorthand 9 | 10 | .fixed-top { 11 | position: fixed; 12 | top: 0; 13 | right: 0; 14 | left: 0; 15 | z-index: $zindex-fixed; 16 | } 17 | 18 | .fixed-bottom { 19 | position: fixed; 20 | right: 0; 21 | bottom: 0; 22 | left: 0; 23 | z-index: $zindex-fixed; 24 | } 25 | 26 | .sticky-top { 27 | @supports (position: sticky) { 28 | position: sticky; 29 | top: 0; 30 | z-index: $zindex-sticky; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_screenreaders.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Screenreaders 3 | // 4 | 5 | .sr-only { 6 | @include sr-only(); 7 | } 8 | 9 | .sr-only-focusable { 10 | @include sr-only-focusable(); 11 | } 12 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_shadows.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | .shadow-sm { box-shadow: $box-shadow-sm !important; } 4 | .shadow { box-shadow: $box-shadow !important; } 5 | .shadow-lg { box-shadow: $box-shadow-lg !important; } 6 | .shadow-none { box-shadow: none !important; } 7 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_sizing.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // Width and height 4 | 5 | @each $prop, $abbrev in (width: w, height: h) { 6 | @each $size, $length in $sizes { 7 | .#{$abbrev}-#{$size} { #{$prop}: $length !important; } 8 | } 9 | } 10 | 11 | .mw-100 { max-width: 100% !important; } 12 | .mh-100 { max-height: 100% !important; } 13 | 14 | // Viewport additional helpers 15 | 16 | .min-vw-100 { min-width: 100vw !important; } 17 | .min-vh-100 { min-height: 100vh !important; } 18 | 19 | .vw-100 { width: 100vw !important; } 20 | .vh-100 { height: 100vh !important; } 21 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_stretched-link.scss: -------------------------------------------------------------------------------- 1 | // 2 | // Stretched link 3 | // 4 | 5 | .stretched-link { 6 | &::after { 7 | position: absolute; 8 | top: 0; 9 | right: 0; 10 | bottom: 0; 11 | left: 0; 12 | z-index: 1; 13 | // Just in case `pointer-events: none` is set on a parent 14 | pointer-events: auto; 15 | content: ""; 16 | // IE10 bugfix, see https://stackoverflow.com/questions/16947967/ie10-hover-pseudo-class-doesnt-work-without-background-color 17 | background-color: rgba(0, 0, 0, 0); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /civictechprojects/static/css/vendor/bootstrap/utilities/_visibility.scss: -------------------------------------------------------------------------------- 1 | // stylelint-disable declaration-no-important 2 | 3 | // 4 | // Visibility utilities 5 | // 6 | 7 | .visible { 8 | visibility: visible !important; 9 | } 10 | 11 | .invisible { 12 | visibility: hidden !important; 13 | } 14 | -------------------------------------------------------------------------------- /civictechprojects/static/images/getstarted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/static/images/getstarted.png -------------------------------------------------------------------------------- /civictechprojects/static/images/login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/static/images/login.png -------------------------------------------------------------------------------- /civictechprojects/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/static/images/logo.png -------------------------------------------------------------------------------- /civictechprojects/static/images/projectPlaceholder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/static/images/projectPlaceholder.png -------------------------------------------------------------------------------- /civictechprojects/static/images/projectlogo-default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/static/images/projectlogo-default.png -------------------------------------------------------------------------------- /civictechprojects/templates/googlebb20bcf8545e7046.html: -------------------------------------------------------------------------------- 1 | google-site-verification: googlebb20bcf8545e7046.html -------------------------------------------------------------------------------- /civictechprojects/templates/robots.txt: -------------------------------------------------------------------------------- 1 | {% if DISALLOW_CRAWLING %} 2 | User-agent: * 3 | Disallow: / 4 | {% else %} 5 | User-agent: * 6 | Allow: / 7 | {% endif %} 8 | 9 | Sitemap: {{PROTOCOL_DOMAIN}}/sitemap.xml -------------------------------------------------------------------------------- /civictechprojects/templates/scripts/google_snippet.txt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 13 | {% if GOOGLE_ADS_ID and GOOGLE_CONVERSION_ID %} 14 | 15 | {% endif %} 16 | -------------------------------------------------------------------------------- /civictechprojects/templates/scripts/google_tag_manager_snippet_body.txt: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /civictechprojects/templates/scripts/google_tag_manager_snippet_head.txt: -------------------------------------------------------------------------------- 1 | 2 | 7 | -------------------------------------------------------------------------------- /civictechprojects/templates/scripts/hotjar_snippet.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /civictechprojects/templates/scripts/org_snippet.txt: -------------------------------------------------------------------------------- 1 | 24 | -------------------------------------------------------------------------------- /civictechprojects/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/civictechprojects/tests/__init__.py -------------------------------------------------------------------------------- /common/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/common/__init__.py -------------------------------------------------------------------------------- /common/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | 3 | from .models import Tag 4 | 5 | tag_text_fields = ['tag_name', 'display_name', 'caption', 'category', 'subcategory', 'parent'] 6 | class TagAdmin(admin.ModelAdmin): 7 | list_display = tuple(tag_text_fields) 8 | search_fields = tag_text_fields 9 | list_filter = ('category', 'subcategory') 10 | 11 | admin.site.register(Tag, TagAdmin) -------------------------------------------------------------------------------- /common/apps.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from django.apps import AppConfig 3 | from django.conf import settings 4 | from common.helpers.db import db_is_initialized 5 | 6 | 7 | class CommonConfig(AppConfig): 8 | name = 'common' 9 | 10 | def ready(self): 11 | self.display_missing_environment_variables() 12 | from common.helpers.tags import import_tags_from_csv 13 | if 'loaddata' in sys.argv: 14 | self.loaddata_clean() 15 | elif db_is_initialized(): 16 | import_tags_from_csv() 17 | 18 | def display_missing_environment_variables(self): 19 | missing_required_variables = [] 20 | for key, value in settings.ENVIRONMENT_VARIABLE_WARNINGS.items(): 21 | if not (hasattr(settings, key)): 22 | if value['error']: 23 | missing_required_variables.append(key) 24 | print(key + ' not set: ' + value['message']) 25 | if len(missing_required_variables) > 0: 26 | raise EnvironmentError('Required environment variables missing: ' + ','.join(missing_required_variables)) 27 | 28 | def loaddata_clean(self): 29 | from django.contrib.contenttypes.models import ContentType 30 | ContentType.objects.all().delete() 31 | -------------------------------------------------------------------------------- /common/caching/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DemocracyLab/CivicTechExchange/fb9ec4d627add9f3974444fb1de009b5bdf7e521/common/caching/__init__.py -------------------------------------------------------------------------------- /common/components/chrome/FlashMessage.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import { Container } from "flux/utils"; 5 | import NavigationStore from "../stores/NavigationStore"; 6 | import _ from "lodash"; 7 | 8 | type State = {| 9 | section: SectionType, 10 | |}; 11 | 12 | class FlashMessage extends React.Component<{||}, State> { 13 | static getStores(): $ReadOnlyArray { 14 | return [NavigationStore]; 15 | } 16 | 17 | static calculateState(prevState: State): State { 18 | return { 19 | section: NavigationStore.getSection(), 20 | }; 21 | } 22 | 23 | componentWillUpdate(nextProps, nextState: State) { 24 | if (nextState.section !== this.state.section) { 25 | window.DLAB_MESSAGES = []; 26 | } 27 | } 28 | 29 | render(): React$Node { 30 | return
{this._renderMessages()}
; 31 | } 32 | 33 | _renderMessages(): React$Node { 34 | return window.DLAB_MESSAGES.map((msg, i) => { 35 | return ( 36 |
37 | {_.unescape(msg.message)} 38 |
39 | ); 40 | }); 41 | } 42 | } 43 | 44 | export default Container.create(FlashMessage); 45 | -------------------------------------------------------------------------------- /common/components/chrome/IconToggle.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import { Glyph } from "../utils/glyphs.js"; 5 | 6 | type Props = {| 7 | toggled: boolean, 8 | toggleOnIconClass: string, 9 | toggleOffIconClass: string, 10 | size: ?string, 11 | |}; 12 | 13 | class IconToggle extends React.PureComponent { 14 | render(): React$Node { 15 | const iconClass: string = this.props.toggled 16 | ? this.props.toggleOnIconClass 17 | : this.props.toggleOffIconClass; 18 | const sizeClass: string = this.props.size || ""; 19 | return ; 20 | } 21 | } 22 | 23 | export default IconToggle; 24 | -------------------------------------------------------------------------------- /common/components/chrome/LoadingFrame.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import { Glyph, GlyphStyles, GlyphSizes } from "../utils/glyphs.js"; 5 | 6 | type Props = {| 7 | height: string, 8 | |}; 9 | 10 | // Placeholder frame with spinner 11 | class LoadingFrame extends React.PureComponent { 12 | constructor(props: Props): void { 13 | super(props); 14 | } 15 | 16 | render() { 17 | return ( 18 |
19 | 20 |
21 | ); 22 | } 23 | } 24 | 25 | export default LoadingFrame; 26 | -------------------------------------------------------------------------------- /common/components/chrome/LoadingMessage.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import { Glyph, GlyphStyles, GlyphSizes } from "../utils/glyphs.js"; 5 | 6 | type Props = {| 7 | message: string, 8 | |}; 9 | 10 | class LoadingMessage extends React.PureComponent { 11 | constructor(props: Props): void { 12 | super(props); 13 | } 14 | 15 | render() { 16 | return ( 17 |
18 | 19 |

{this.props.message}

20 |
21 | ); 22 | } 23 | } 24 | 25 | export default LoadingMessage; 26 | -------------------------------------------------------------------------------- /common/components/chrome/PseudoLink.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | 5 | type Props = {| 6 | +text: string, 7 | +onClick: () => void, 8 | |}; 9 | 10 | class PseudoLink extends React.PureComponent { 11 | onClick(e): void { 12 | // Prevent any page navigation 13 | e.preventDefault(); 14 | this.props.onClick(); 15 | } 16 | 17 | render(): React$Node { 18 | // TODO: Implement with styled text instead of anchor 19 | return ( 20 |
21 | {this.props.text} 22 | 23 | ); 24 | } 25 | } 26 | 27 | export default PseudoLink; 28 | -------------------------------------------------------------------------------- /common/components/common/FileInfo.jsx: -------------------------------------------------------------------------------- 1 | export type FileInfo = {| 2 | id: ?number, 3 | key: string, 4 | fileName: string, 5 | fileCategory: string, 6 | publicUrl: string, 7 | visibility: ?string, 8 | |}; 9 | -------------------------------------------------------------------------------- /common/components/common/JumpAnchor.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import { Container } from "flux/utils"; 5 | import type { FluxReduceStore } from "flux/utils"; 6 | import PageOffsetStore from "../stores/PageOffsetStore.js"; 7 | 8 | type Props = {| 9 | id: string, 10 | |}; 11 | 12 | type State = {| 13 | headerHeight: number, 14 | |}; 15 | 16 | // Anchor target that adjusts for the top header height 17 | class JumpAnchor extends React.Component { 18 | static getStores(): $ReadOnlyArray { 19 | return [PageOffsetStore]; 20 | } 21 | 22 | static calculateState(prevState: State): State { 23 | return { 24 | headerHeight: PageOffsetStore.getHeaderHeight(), 25 | }; 26 | } 27 | 28 | render(): React$Node { 29 | const style = { 30 | position: "absolute", 31 | top: -this.state.headerHeight, 32 | }; 33 | 34 | return ( 35 | 36 | 37 | 38 | ); 39 | } 40 | } 41 | 42 | export default Container.create(JumpAnchor); 43 | -------------------------------------------------------------------------------- /common/components/common/StepIndicatorBars.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import _ from "lodash"; 5 | 6 | type Props = {| 7 | stepCount: number, 8 | currentlySelected: number, 9 | |}; 10 | 11 | /** 12 | * Generic Modal designed to solicit feedback 13 | */ 14 | class StepIndicatorBars extends React.PureComponent { 15 | constructor(props: Props): void { 16 | super(props); 17 | } 18 | 19 | render(): React$Node { 20 | return ( 21 |
22 | {_.range(this.props.stepCount).map((step: number) => 23 | this._renderStepBar(step) 24 | )} 25 |
26 | ); 27 | } 28 | 29 | _renderStepBar(idx: number): React$Node { 30 | return ( 31 |
37 | ); 38 | } 39 | } 40 | 41 | export default StepIndicatorBars; 42 | -------------------------------------------------------------------------------- /common/components/common/Visibility.jsx: -------------------------------------------------------------------------------- 1 | // This should always be kept in sync with /common/models/visibility.py 2 | const Visibility = { 3 | PUBLIC: "PUBLIC", 4 | }; 5 | 6 | export default Visibility; 7 | -------------------------------------------------------------------------------- /common/components/common/avatar.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import Person from "../svg/person.svg"; 5 | import type { UserAPIData } from "../../utils/UserAPIUtils"; 6 | 7 | type Props = {| 8 | +user: UserAPIData, 9 | +imgClass: string, 10 | |}; 11 | 12 | class Avatar extends React.PureComponent { 13 | render(): React$Node { 14 | const user = this.props.user; 15 | return user.user_thumbnail ? ( 16 | 20 | ) : ( 21 | 22 | 23 | 24 | ); 25 | } 26 | } 27 | 28 | export default Avatar; 29 | -------------------------------------------------------------------------------- /common/components/common/event_projects/JoinConferenceButton.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import Button from "react-bootstrap/Button"; 5 | import { Glyph, GlyphSizes, GlyphStyles } from "../../utils/glyphs.js"; 6 | import type { Dictionary } from "../../types/Generics.jsx"; 7 | 8 | type Props = {| 9 | buttonConfig: Dictionary, 10 | participant_count: number, 11 | className: ?string, 12 | variant: string, 13 | |}; 14 | 15 | /** 16 | * Button for presenting conference links with participant count 17 | */ 18 | 19 | class JoinConferenceButton extends React.PureComponent { 20 | constructor(props: Props): void { 21 | super(props); 22 | } 23 | 24 | render(): React$Node { 25 | return ( 26 | 27 | 36 | 37 | ); 38 | } 39 | } 40 | 41 | export default JoinConferenceButton; 42 | -------------------------------------------------------------------------------- /common/components/common/location/LocationRadius.js: -------------------------------------------------------------------------------- 1 | export type LocationRadius = {| 2 | latitude: number, 3 | longitude: number, 4 | radius: number, 5 | |}; 6 | 7 | export function locationRadiusToString(locationRadius: LocationRadius): string { 8 | return `${locationRadius.latitude},${locationRadius.longitude},${locationRadius.radius}`; 9 | } 10 | 11 | export function locationRadiusFromString(str: string): LocationRadius { 12 | const parts: $ReadOnlyArray = str && str.split(","); 13 | return ( 14 | parts && 15 | parts.length > 2 && { 16 | latitude: parseFloat(parts[0]), 17 | longitude: parseFloat(parts[1]), 18 | radius: parseInt(parts[2]), 19 | } 20 | ); 21 | } 22 | -------------------------------------------------------------------------------- /common/components/common/owners/ProjectOwnerCard.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import { UserAPIData } from "../../utils/UserAPIUtils.js"; 5 | import { 6 | TagDefinition, 7 | VolunteerUserData, 8 | } from "../../utils/ProjectAPIUtils.js"; 9 | import url from "../../utils/url.js"; 10 | import Section from "../../enums/Section.js"; 11 | import Avatar from "../avatar.jsx"; 12 | 13 | type Props = {| 14 | +owner: VolunteerUserData, 15 | |}; 16 | 17 | class ProjectOwnerCard extends React.PureComponent { 18 | render(): React$Node { 19 | const owner: ?VolunteerUserData = this.props.owner; 20 | const ownerUrl: string = url.section(Section.Profile, { id: owner.id }); 21 | return ( 22 | 31 | ); 32 | } 33 | } 34 | 35 | export default ProjectOwnerCard; 36 | -------------------------------------------------------------------------------- /common/components/common/richtext/AllowMarkdown.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import ReactMarkdown from "react-markdown"; 5 | 6 | class AllowMarkdown extends React.PureComponent { 7 | render(): React$Node { 8 | // Disallow headers so as not to interfere with set header hierarchy of page 9 | // Disallow list elements because they interact poorly with pre-wrap 10 | const disallowedElements: ReadonlyArray = [ 11 | "h1", 12 | "h2", 13 | "h3", 14 | "h4", 15 | "h5", 16 | "h6", 17 | ]; 18 | return ( 19 | 24 | {this.props.children} 25 | 26 | ); 27 | } 28 | } 29 | 30 | export default AllowMarkdown; 31 | -------------------------------------------------------------------------------- /common/components/common/tags/TagCategory.jsx: -------------------------------------------------------------------------------- 1 | // This should always be kept in sync with Categories used in /common/models/Tag_definitions.csv 2 | const TagCategory = { 3 | ISSUES: "Issue(s) Addressed", 4 | PROJECT_CATEGORY: "Project Category", 5 | PROJECT_NEED: "Project Need", 6 | PROJECT_STAGE: "Project Stage", 7 | SOFTWARE_LICENSE: "Software License", 8 | STATUS: "Status", 9 | TECHNOLOGIES_USED: "Technologies Used", 10 | ROLE: "Role", 11 | ORGANIZATION: "Organization", 12 | ORGANIZATION_TYPE: "Organization Type", 13 | }; 14 | 15 | export default TagCategory; 16 | -------------------------------------------------------------------------------- /common/components/common/tags/TagsDisplay.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import type { TagDefinition } from "../../../components/utils/ProjectAPIUtils.js"; 5 | 6 | type Props = {| 7 | tags: $ReadOnlyArray, 8 | |}; 9 | 10 | /** 11 | * Displays tags 12 | */ 13 | class TagsDisplay extends React.PureComponent { 14 | constructor(props: Props): void { 15 | super(props); 16 | } 17 | 18 | render(): React$Node { 19 | return ( 20 |
21 | {this.props.tags.map(tag => ( 22 | 27 | {tag.display_name} 28 | 29 | ))} 30 |
31 | ); 32 | } 33 | } 34 | 35 | export default TagsDisplay; 36 | -------------------------------------------------------------------------------- /common/components/common/upload/S3Data.jsx: -------------------------------------------------------------------------------- 1 | export type S3Data = {| 2 | url: string, 3 | fields: { 4 | key: string, 5 | }, 6 | |}; 7 | -------------------------------------------------------------------------------- /common/components/common/video/VideoModal.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import ModalWrapper, { ModalSizes } from "../ModalWrapper.jsx"; 5 | import VideoWrapper from "./VideoWrapper.jsx"; 6 | 7 | type Props = {| 8 | showModal: boolean, 9 | videoUrl: string, 10 | videoTitle: string, 11 | onClose: () => void, 12 | |}; 13 | type State = {| 14 | showModal: boolean, 15 | |}; 16 | 17 | /** 18 | * Modal for showing videos 19 | */ 20 | class VideoModal extends React.PureComponent { 21 | constructor(props: Props): void { 22 | super(props); 23 | this.state = { 24 | showModal: false, 25 | }; 26 | } 27 | 28 | componentWillReceiveProps(nextProps: Props): void { 29 | this.setState({ showModal: nextProps.showModal }); 30 | } 31 | 32 | render(): React$Node { 33 | return ( 34 | 41 | 42 | 43 | ); 44 | } 45 | } 46 | 47 | export default VideoModal; 48 | -------------------------------------------------------------------------------- /common/components/common/video/VideoWrapper.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | 5 | type Props = {| 6 | videoUrl: string, 7 | |}; 8 | 9 | // Shows embedded video 10 | class VideoController extends React.PureComponent { 11 | constructor(): void { 12 | super(); 13 | } 14 | 15 | render(): React$Node { 16 | return ( 17 |
18 | 27 |
28 | ); 29 | } 30 | } 31 | 32 | export default VideoController; 33 | -------------------------------------------------------------------------------- /common/components/componentsBySection/CreateEvent/EventFormCommon.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | 5 | type FunctionCallback = (?Function) => void; 6 | export type OnReadySubmitFunc = (boolean, FunctionCallback) => void; 7 | -------------------------------------------------------------------------------- /common/components/componentsBySection/CreateEvent/EventPreviewForm.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import DjangoCSRFToken from "django-react-csrftoken"; 5 | import { OnReadySubmitFunc } from "./EventFormCommon.jsx"; 6 | import AboutEventDisplay from "./AboutEventDisplay.jsx"; 7 | import type { EventData } from "../../utils/EventAPIUtils.js"; 8 | 9 | type Props = {| 10 | project: ?EventData, 11 | readyForSubmit: OnReadySubmitFunc, 12 | |}; 13 | 14 | /** 15 | * Shows preview for project before finalizing 16 | */ 17 | class EventPreviewForm extends React.PureComponent { 18 | constructor(props: Props): void { 19 | super(props); 20 | // All fields optional 21 | props.readyForSubmit(true); 22 | } 23 | 24 | render(): React$Node { 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | export default EventPreviewForm; 36 | -------------------------------------------------------------------------------- /common/components/componentsBySection/CreateGroup/GroupFormCommon.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | 5 | type FunctionCallback = (?Function) => void; 6 | export type OnReadySubmitFunc = (boolean, FunctionCallback) => void; 7 | -------------------------------------------------------------------------------- /common/components/componentsBySection/CreateGroup/GroupPreviewForm.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import DjangoCSRFToken from "django-react-csrftoken"; 5 | import type { GroupDetailsAPIData } from "../../../components/utils/GroupAPIUtils.js"; 6 | import AboutGroupDisplay from "../../common/groups/AboutGroupDisplay.jsx"; 7 | import { OnReadySubmitFunc } from "./GroupFormCommon.jsx"; 8 | 9 | type Props = {| 10 | project: ?GroupDetailsAPIData, // TODO: Fix the key this is passed down as 11 | readyForSubmit: OnReadySubmitFunc, 12 | |}; 13 | 14 | /** 15 | * Shows preview for Group before finalizing 16 | */ 17 | class GroupPreviewForm extends React.PureComponent { 18 | constructor(props: Props): void { 19 | super(props); 20 | // All fields optional 21 | props.readyForSubmit(true); 22 | } 23 | 24 | render(): React$Node { 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | export default GroupPreviewForm; 36 | -------------------------------------------------------------------------------- /common/components/componentsBySection/CreateProject/ProjectFormCommon.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | 5 | type FunctionCallback = (?Function) => void; 6 | export type OnReadySubmitFunc = (boolean, FunctionCallback) => void; 7 | -------------------------------------------------------------------------------- /common/components/componentsBySection/CreateProject/ProjectPreviewForm.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import DjangoCSRFToken from "django-react-csrftoken"; 5 | import type { ProjectDetailsAPIData } from "../../../components/utils/ProjectAPIUtils.js"; 6 | import AboutProjectDisplay from "../../common/projects/AboutProjectDisplay.jsx"; 7 | import { OnReadySubmitFunc } from "./ProjectFormCommon.jsx"; 8 | 9 | type Props = {| 10 | project: ?ProjectDetailsAPIData, 11 | readyForSubmit: OnReadySubmitFunc, 12 | |}; 13 | 14 | /** 15 | * Shows preview for project before finalizing 16 | */ 17 | class ProjectPreviewForm extends React.PureComponent { 18 | constructor(props: Props): void { 19 | super(props); 20 | // All fields optional 21 | props.readyForSubmit(true); 22 | } 23 | 24 | render(): React$Node { 25 | return ( 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | } 33 | } 34 | 35 | export default ProjectPreviewForm; 36 | -------------------------------------------------------------------------------- /common/components/componentsBySection/FindGroups/FIlters/GroupFilterContainer.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from "react"; 3 | import GroupFilterDataContainer from "./GroupFilterDataContainer.jsx"; 4 | import ResetSearchButton from "../../FindProjects/ResetSearchButton.jsx"; 5 | 6 | class GroupFilterContainer extends React.PureComponent<{||}> { 7 | render(): React$Node { 8 | return ( 9 |
10 |
11 | 12 |
13 | 14 |
15 | ); 16 | } 17 | } 18 | 19 | export default GroupFilterContainer; 20 | -------------------------------------------------------------------------------- /common/components/componentsBySection/FindProjects/CloseablePill.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import GlyphStyles from "../../utils/glyphs.js"; 4 | import React from "react"; 5 | 6 | type Props = {| 7 | label: string, 8 | closeAction: () => void, 9 | |}; 10 | 11 | class CloseablePill extends React.PureComponent { 12 | render(): React$Node { 13 | return ( 14 | 15 | {this.props.label} 16 | {this._renderCloseButton()} 17 | 18 | ); 19 | } 20 | 21 | onClickCloseButton(event) { 22 | event.stopPropagation(); 23 | this.props.closeAction(); 24 | } 25 | 26 | _renderCloseButton(): React$Node { 27 | return ( 28 | 32 | 33 | 34 | ); 35 | } 36 | } 37 | 38 | export default CloseablePill; 39 | -------------------------------------------------------------------------------- /common/components/componentsBySection/FindProjects/Filters/ProjectFilterContainer.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from "react"; 3 | import ProjectFilterDataContainer from "./ProjectFilterDataContainer.jsx"; 4 | import ResetSearchButton from "../ResetSearchButton.jsx"; 5 | import metrics from "../../../utils/metrics.js"; 6 | 7 | class ProjectFilterContainer extends React.PureComponent, State> { 8 | render(): React$Node { 9 | return ( 10 |
11 |
12 | 13 |
14 | 15 |
16 | ); 17 | } 18 | } 19 | 20 | export default ProjectFilterContainer; 21 | -------------------------------------------------------------------------------- /common/components/componentsBySection/signUp/SignUpErrorAdapter.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import SignUpController from "../../controllers/SignUpController.jsx"; 5 | 6 | type Props = {| 7 | +json_encoded_errors: string, 8 | |}; 9 | 10 | class SignUpErrorAdapter extends React.Component { 11 | render(): React$Node { 12 | return ; 13 | } 14 | 15 | // e.g. {password: ['Password too short.', 'Password too similar.'], ...} 16 | _getErrors(): { +[key: string]: $ReadOnlyArray } { 17 | const structuredErrors = {}; 18 | if (this.props.json_encoded_errors) { 19 | const decodedErrors = JSON.parse(this.props.json_encoded_errors); 20 | Object.keys(decodedErrors).forEach(field => { 21 | structuredErrors[field] = decodedErrors[field].map(e => e.message); 22 | }); 23 | } 24 | return structuredErrors; 25 | } 26 | } 27 | 28 | export default SignUpErrorAdapter; 29 | -------------------------------------------------------------------------------- /common/components/constants/FileConstants.js: -------------------------------------------------------------------------------- 1 | export const FileCategoryNames = { 2 | RESUME: "Resume", 3 | }; 4 | -------------------------------------------------------------------------------- /common/components/controllers/ContactUsController.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import ContactForm from "../forms/ContactForm.jsx"; 5 | 6 | class ContactUsController extends React.PureComponent<{||}> { 7 | 8 | render(): $React$Node { 9 | return ( 10 | 11 |
12 |
13 |
14 |

Contact Us

15 |

16 | To contact DemocracyLab, please fill out this form to send us a 17 | message and we'll get back to you. All fields are required. 18 |

19 | 20 |
21 |
22 |
23 |
24 | ); 25 | } 26 | } 27 | 28 | export default ContactUsController; 29 | -------------------------------------------------------------------------------- /common/components/controllers/IframeGroupController.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | import React from "react"; 3 | import AboutGroupController from "./AboutGroupController.jsx"; 4 | import IframeGroupDisplay from "../common/groups/IframeGroupDisplay.jsx"; 5 | 6 | export default class IframeGroupController extends AboutGroupController<{||}, State> { 7 | _renderDetails(): React$Node { 8 | return ( 9 | 10 | 11 | 12 | ); 13 | } 14 | } 15 | 16 | -------------------------------------------------------------------------------- /common/components/controllers/LiveEventController.jsx: -------------------------------------------------------------------------------- 1 | // @flow 2 | 3 | import React from "react"; 4 | import CurrentUser from "../utils/CurrentUser.js"; 5 | import LogInController from "./LogInController.jsx"; 6 | import Section from "../enums/Section.js"; 7 | import urlHelper from "../utils/url.js"; 8 | import _ from "lodash"; 9 | 10 | type State = {| 11 | iframeUrl: string, 12 | |}; 13 | 14 | class LiveEventController extends React.Component<{||}, State> { 15 | constructor(): void { 16 | super(); 17 | 18 | this.state = { 19 | iframeUrl: window.QIQO_IFRAME_URL.replace( 20 | "EVENT_ID", 21 | urlHelper.argument("id") 22 | ), 23 | }; 24 | } 25 | 26 | render(): React$Node { 27 | return !CurrentUser.isLoggedIn() ? ( 28 | 29 | ) : ( 30 |
31 |