├── .github ├── dependabot.yml └── workflows │ ├── backend.yml │ ├── frontend.yml │ └── native.yml ├── .gitignore ├── .ruby-gemset ├── .ruby-version ├── .tool-versions ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── LICENSE.txt ├── Makefile ├── README.md ├── Rakefile ├── app └── components │ └── g-recaptcha.js ├── backend ├── .gitignore ├── .pryrc ├── .rspec ├── .ruby-version ├── .standard_todo.yml ├── .tool-versions ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── Procfile ├── Procfile.local ├── Rakefile ├── app │ ├── assets │ │ ├── config │ │ │ └── manifest.js │ │ ├── images │ │ │ └── .keep │ │ ├── javascripts │ │ │ └── .gitkeep │ │ └── stylesheets │ │ │ └── .gitkeep │ ├── controllers │ │ ├── api │ │ │ └── v1 │ │ │ │ ├── aws_ses_controller.rb │ │ │ │ ├── chart_lists_controller.rb │ │ │ │ ├── charts_controller.rb │ │ │ │ ├── charts_pattern_controller.rb │ │ │ │ ├── checkins_controller.rb │ │ │ │ ├── comments_controller.rb │ │ │ │ ├── conditions_controller.rb │ │ │ │ ├── countries_controller.rb │ │ │ │ ├── data_export_schedules_controller.rb │ │ │ │ ├── day_habits_controller.rb │ │ │ │ ├── discourses_controller.rb │ │ │ │ ├── education_levels_controller.rb │ │ │ │ ├── ethnicities_controller.rb │ │ │ │ ├── foods_controller.rb │ │ │ │ ├── harvey_bradshaw_indices_controller.rb │ │ │ │ ├── invitations_controller.rb │ │ │ │ ├── notifications_controller.rb │ │ │ │ ├── omniauth_callbacks_controller.rb │ │ │ │ ├── oracle_requests_controller.rb │ │ │ │ ├── passwords_controller.rb │ │ │ │ ├── patterns_controller.rb │ │ │ │ ├── postables_controller.rb │ │ │ │ ├── posts_controller.rb │ │ │ │ ├── profiles_controller.rb │ │ │ │ ├── promotion_rates_controller.rb │ │ │ │ ├── pushers_controller.rb │ │ │ │ ├── reactions_controller.rb │ │ │ │ ├── registrations_controller.rb │ │ │ │ ├── searches_controller.rb │ │ │ │ ├── sessions_controller.rb │ │ │ │ ├── sexes_controller.rb │ │ │ │ ├── symptoms_controller.rb │ │ │ │ ├── tags_controller.rb │ │ │ │ ├── topic_followings_controller.rb │ │ │ │ ├── trackings_controller.rb │ │ │ │ ├── treatments_controller.rb │ │ │ │ ├── unsubscribes_controller.rb │ │ │ │ ├── users_controller.rb │ │ │ │ └── weathers_controller.rb │ │ ├── application_controller.rb │ │ └── concerns │ │ │ ├── .keep │ │ │ └── exception_logger.rb │ ├── extenders │ │ ├── pattern_extender.rb │ │ └── post_extender.rb │ ├── jobs │ │ ├── application_job.rb │ │ ├── checkin_reminder_job.rb │ │ ├── data_export_job.rb │ │ ├── discussion_mention.rb │ │ ├── email_reject_dispatcher.rb │ │ ├── email_reject_job.rb │ │ ├── group_notifiers_per_user.rb │ │ ├── group_top_posts_job.rb │ │ ├── hello_world_job.rb │ │ ├── merge_trackables │ │ │ ├── checkin_trackables.rb │ │ │ ├── dispatcher.rb │ │ │ ├── pattern_includes.rb │ │ │ ├── post_trackables.rb │ │ │ ├── remove_duplicates.rb │ │ │ ├── topic_following.rb │ │ │ ├── trackable_usages.rb │ │ │ ├── trackings.rb │ │ │ └── user_trackable_association.rb │ │ ├── notes_export_job.rb │ │ ├── notification_dispatcher.rb │ │ ├── position_reference_job.rb │ │ ├── same_trackables_job.rb │ │ ├── switch_trackable_visibility.rb │ │ ├── top_posts_mailer_dispatcher.rb │ │ ├── update_checkin_reminders.rb │ │ └── update_post_counters_job.rb │ ├── mailers │ │ ├── application_mailer.rb │ │ ├── checkin_reminder_mailer.rb │ │ ├── notifications_mailer.rb │ │ ├── promotion_rate │ │ │ ├── low_rate_mailer.rb │ │ │ └── statistic_mailer.rb │ │ ├── top_posts_mailer.rb │ │ └── user_data_mailer.rb │ ├── models │ │ ├── ability.rb │ │ ├── application_record.rb │ │ ├── chart.rb │ │ ├── checkin.rb │ │ ├── checkin │ │ │ ├── fiveable.rb │ │ │ └── trackable.rb │ │ ├── comment.rb │ │ ├── concerns │ │ │ ├── authenticatable.rb │ │ │ ├── topicable.rb │ │ │ └── usernameable.rb │ │ ├── condition.rb │ │ ├── day_habit.rb │ │ ├── dose.rb │ │ ├── education_level.rb │ │ ├── ethnicity.rb │ │ ├── feedback.rb │ │ ├── food.rb │ │ ├── harvey_bradshaw_index.rb │ │ ├── invitation.rb │ │ ├── notification.rb │ │ ├── oracle_request.rb │ │ ├── pattern.rb │ │ ├── position.rb │ │ ├── post.rb │ │ ├── postable.rb │ │ ├── profile.rb │ │ ├── promotion_rate.rb │ │ ├── ranked_enum.rb │ │ ├── reaction.rb │ │ ├── registration.rb │ │ ├── search.rb │ │ ├── search │ │ │ ├── for_dose.rb │ │ │ ├── for_food.rb │ │ │ └── for_topic.rb │ │ ├── sex.rb │ │ ├── symptom.rb │ │ ├── tag.rb │ │ ├── topic_following.rb │ │ ├── trackable_usage.rb │ │ ├── tracking.rb │ │ ├── treatment.rb │ │ ├── user.rb │ │ ├── user_condition.rb │ │ ├── user_food.rb │ │ ├── user_symptom.rb │ │ ├── user_tag.rb │ │ ├── user_treatment.rb │ │ └── weather.rb │ ├── serializers │ │ ├── api │ │ │ └── v1 │ │ │ │ ├── chart_serializer.rb │ │ │ │ ├── checkin_condition_serializer.rb │ │ │ │ ├── checkin_serializer.rb │ │ │ │ ├── checkin_symptom_serializer.rb │ │ │ │ ├── checkin_trackable_serializer.rb │ │ │ │ ├── checkin_treatment_serializer.rb │ │ │ │ ├── comment_serializer.rb │ │ │ │ ├── concerns.rb │ │ │ │ ├── concerns │ │ │ │ ├── notificatable.rb │ │ │ │ ├── reaction_relatable.rb │ │ │ │ └── topic_serializable.rb │ │ │ │ ├── condition_serializer.rb │ │ │ │ ├── country_serializer.rb │ │ │ │ ├── day_habit_serializer.rb │ │ │ │ ├── dose_serializer.rb │ │ │ │ ├── education_level_serializer.rb │ │ │ │ ├── ethnicity_serializer.rb │ │ │ │ ├── food_serializer.rb │ │ │ │ ├── harvey_bradshaw_index_serializer.rb │ │ │ │ ├── invitation_serializer.rb │ │ │ │ ├── oracle_request_serializer.rb │ │ │ │ ├── oracle_request_with_token_serializer.rb │ │ │ │ ├── password_serializer.rb │ │ │ │ ├── pattern_serializer.rb │ │ │ │ ├── post_serializer.rb │ │ │ │ ├── postable_serializer.rb │ │ │ │ ├── profile_serializer.rb │ │ │ │ ├── promotion_rate_serializer.rb │ │ │ │ ├── ranked_enum_serializer.rb │ │ │ │ ├── reaction_serializer.rb │ │ │ │ ├── registration_serializer.rb │ │ │ │ ├── search_serializer.rb │ │ │ │ ├── searchable_serializer.rb │ │ │ │ ├── session_serializer.rb │ │ │ │ ├── sex_serializer.rb │ │ │ │ ├── symptom_serializer.rb │ │ │ │ ├── tag_serializer.rb │ │ │ │ ├── topic_following_serializer.rb │ │ │ │ ├── trackable_serializer.rb │ │ │ │ ├── tracking_serializer.rb │ │ │ │ ├── treatment_serializer.rb │ │ │ │ ├── user_serializer.rb │ │ │ │ └── weather_serializer.rb │ │ └── application_serializer.rb │ ├── services │ │ ├── additional_posts.rb │ │ ├── chart_list_service.rb │ │ ├── charts_pattern.rb │ │ ├── checkin │ │ │ ├── creator.rb │ │ │ └── updater.rb │ │ ├── collection_retriever.rb │ │ ├── discussion_posts.rb │ │ ├── google │ │ │ └── recaptcha_verifier.rb │ │ ├── pattern_creator.rb │ │ ├── summary_posts.rb │ │ ├── trackable_creator.rb │ │ ├── tracking_destroyer.rb │ │ └── weather_retriever.rb │ └── views │ │ ├── checkin_reminder_mailer │ │ └── remind.html.erb │ │ ├── devise │ │ └── mailer │ │ │ ├── invitation_instructions.html.erb │ │ │ └── reset_password_instructions.html.erb │ │ ├── layouts │ │ └── mailer_layout.html.erb │ │ ├── notifications_mailer │ │ └── notify.html.erb │ │ ├── promotion_rate │ │ ├── low_rate_mailer │ │ │ └── show.html.erb │ │ └── statistic_mailer │ │ │ └── show.html.erb │ │ ├── top_posts_mailer │ │ └── notify.html.erb │ │ └── user_data_mailer │ │ └── trackings_csv.text.erb ├── bin │ ├── bundle │ ├── rails │ ├── rake │ ├── rspec │ ├── setup │ ├── system_spec │ └── update ├── config.ru ├── config │ ├── application.rb │ ├── boot.rb │ ├── cronotab.rb │ ├── database.yml │ ├── environment.rb │ ├── environments │ │ ├── development.rb │ │ ├── production.rb │ │ └── test.rb │ ├── initializers │ │ ├── 00_app.rb │ │ ├── action_mailer.rb │ │ ├── active_model_serializers.rb │ │ ├── application_controller_renderer.rb │ │ ├── assets.rb │ │ ├── backtrace_silencers.rb │ │ ├── bugsnag.rb │ │ ├── content_security_policy.rb │ │ ├── devise.rb │ │ ├── filter_parameter_logging.rb │ │ ├── inflections.rb │ │ ├── mime_types.rb │ │ ├── mongoid.rb │ │ ├── new_framework_defaults_7_1.rb │ │ ├── permissions_policy.rb │ │ ├── preview_interceptors.rb │ │ ├── rack_timeout.rb │ │ ├── sidekiq.rb │ │ └── tomorrowio_rb.rb │ ├── locales │ │ ├── en.yml │ │ └── it.yml │ ├── mongoid.yml │ ├── puma.rb │ ├── routes.rb │ ├── secrets.yml │ ├── sidekiq.yml │ └── symmetric-encryption.yml ├── db │ ├── migrate │ │ ├── 20160101154821_create_extensions.rb │ │ ├── 20160106154821_create_users.rb │ │ ├── 20160119185831_create_profiles.rb │ │ ├── 20160128112500_create_conditions.rb │ │ ├── 20160128114341_create_user_conditions.rb │ │ ├── 20160128191053_create_symptoms.rb │ │ ├── 20160128191329_create_user_symptoms.rb │ │ ├── 20160128210332_create_trackings.rb │ │ ├── 20160129063945_create_treatments.rb │ │ ├── 20160129064538_create_user_treatments.rb │ │ ├── 20160211105611_create_tags.rb │ │ ├── 20160224141256_add_demographics_to_profiles.rb │ │ ├── 20160404073700_enable_hstore_extension.rb │ │ ├── 20160404073731_add_most_recent_doses_to_profiles.rb │ │ ├── 20160426222232_create_trackable_usages.rb │ │ ├── 20160427055217_add_trackable_usages_counts.rb │ │ ├── 20160608161002_add_screen_name_to_profile.rb │ │ ├── 20160711182546_add_most_recent_positions_to_profiles.rb │ │ ├── 20161206135858_create_foods.rb │ │ ├── 20161214131805_add_long_desc_vector_index_on_food_translations.rb │ │ ├── 20161216123757_create_weathers.rb │ │ ├── 20161230090023_add_pressure_and_temperature_settings_to_profile.rb │ │ ├── 20170413144043_add_beta_tester_to_profile.rb │ │ ├── 20170504065043_create_crono_jobs.rb │ │ ├── 20170508151200_add_notify_to_profiles.rb │ │ ├── 20170509114220_add_notify_token_to_profiles.rb │ │ ├── 20170612160120_add_slug_name_to_profiles.rb │ │ ├── 20170717153650_add_notify_top_posts_to_profile.rb │ │ ├── 20170731083613_add_global_to_foods_and_tags.rb │ │ ├── 20170731123835_add_trackable_usage_count_to_tags.rb │ │ ├── 20170731125044_create_user_tags.rb │ │ ├── 20170801124153_add_trackable_ability_to_foods.rb │ │ ├── 20170817154145_create_positions.rb │ │ ├── 20170818085110_add_position_reference_to_weather.rb │ │ ├── 20170822122800_add_checkin_reminder_to_profiles.rb │ │ └── 20171011142928_add_rejected_type_to_profiles.rb │ ├── schema.rb │ ├── seeds.rb │ ├── seeds │ │ ├── conditions.seeds.rb │ │ ├── development │ │ │ ├── checkins.seeds.rb │ │ │ └── users.seeds.rb │ │ ├── symptoms.seeds.rb │ │ └── treatments.seeds.rb │ └── structure.sql ├── env-example ├── lib │ ├── discourse_client.rb │ ├── flaredown │ │ └── colorable.rb │ ├── pusher_client.rb │ └── tasks │ │ ├── app.rake │ │ ├── encrypt_user_id.rake │ │ ├── hbi_completeness.rake │ │ ├── notifications_scheduler.rake │ │ ├── oneoff.rake │ │ ├── rubocop.rake │ │ ├── spec.rake │ │ ├── trackables.rake │ │ ├── usda.rake │ │ ├── utils.rake │ │ └── weekly_top_posts_scheduler.rake ├── log │ └── .keep ├── package-lock.json ├── public │ ├── 404.html │ ├── 422.html │ ├── 500.html │ ├── favicon.ico │ ├── images │ │ └── optional_email_img.png │ └── robots.txt ├── spec │ ├── controllers │ │ └── api │ │ │ └── v1 │ │ │ ├── checkins_controller_spec.rb │ │ │ ├── conditions_controller_spec.rb │ │ │ ├── countries_controller_spec.rb │ │ │ ├── day_habits_controller_spec.rb │ │ │ ├── education_levels_controller_spec.rb │ │ │ ├── ethnicities_controller_spec.rb │ │ │ ├── passwords_controller_spec.rb │ │ │ ├── posts_controller_spec.rb │ │ │ ├── profiles_controller_spec.rb │ │ │ ├── registrations_controller_spec.rb │ │ │ ├── searches_controller_spec.rb │ │ │ ├── sexes_controller_spec.rb │ │ │ ├── symptoms_controller_spec.rb │ │ │ ├── tags_controller_spec.rb │ │ │ ├── trackings_controller_spec.rb │ │ │ ├── treatments_controller_spec.rb │ │ │ ├── users_controller_spec.rb │ │ │ └── weathers_controller_spec.rb │ ├── factories │ │ ├── checkin │ │ │ ├── conditions.rb │ │ │ ├── symptoms.rb │ │ │ └── treatments.rb │ │ ├── checkins.rb │ │ ├── comments.rb │ │ ├── conditions.rb │ │ ├── foods.rb │ │ ├── notifications.rb │ │ ├── patterns.rb │ │ ├── posts.rb │ │ ├── profiles.rb │ │ ├── promotion_rate.rb │ │ ├── reactions.rb │ │ ├── symptoms.rb │ │ ├── tags.rb │ │ ├── topic_followings.rb │ │ ├── trackable_usages.rb │ │ ├── trackings.rb │ │ ├── treatments.rb │ │ ├── user_conditions.rb │ │ ├── user_foods.rb │ │ ├── user_symptoms.rb │ │ ├── user_tags.rb │ │ ├── user_treatments.rb │ │ ├── users.rb │ │ └── weathers.rb │ ├── fixtures │ │ ├── usda │ │ │ └── FOOD_DES.txt │ │ └── vcr_cassettes │ │ │ ├── Google_RecaptchaVerifier │ │ │ ├── given_a_non-expired_ReCaptcha_response │ │ │ │ └── returns_true.yml │ │ │ └── given_an_expired_ReCaptcha_response │ │ │ │ └── returns_false.yml │ │ │ └── WeatherRetriever │ │ │ ├── 55403.yml │ │ │ └── the_weather_is_already_cached │ │ │ ├── 1_2_1.yml │ │ │ └── 1_2_2.yml │ ├── jobs │ │ ├── data_export_job_spec.rb │ │ └── switch_trackable_visibility_spec.rb │ ├── mailers │ │ ├── checkin_reminder_mailer_spec.rb │ │ ├── previews │ │ │ ├── checkin_reminder_mailer_preview.rb │ │ │ ├── top_posts_mailer_preview.rb │ │ │ └── user_data_mailer_preview.rb │ │ └── user_data_mailer_spec.rb │ ├── models │ │ ├── ability │ │ │ ├── condition_spec.rb │ │ │ ├── food_spec.rb │ │ │ ├── symptom_spec.rb │ │ │ ├── tag_spec.rb │ │ │ └── treatment_spec.rb │ │ ├── checkin │ │ │ ├── condition_spec.rb │ │ │ ├── symptom_spec.rb │ │ │ └── treatment_spec.rb │ │ ├── checkin_spec.rb │ │ ├── comment_spec.rb │ │ ├── condition_spec.rb │ │ ├── food_spec.rb │ │ ├── harvey_bradshaw_index.rb │ │ ├── notification_spec.rb │ │ ├── position_spec.rb │ │ ├── post_spec.rb │ │ ├── profile_spec.rb │ │ ├── promotion_rate_spec.rb │ │ ├── ranked_enum_spec.rb │ │ ├── reaction_spec.rb │ │ ├── registration_spec.rb │ │ ├── search │ │ │ └── for_dose_spec.rb │ │ ├── search_spec.rb │ │ ├── symptom_spec.rb │ │ ├── tag_spec.rb │ │ ├── topic_following_spec.rb │ │ ├── trackable_usage_spec.rb │ │ ├── tracking_spec.rb │ │ ├── treatment_spec.rb │ │ ├── user_condition_spec.rb │ │ ├── user_spec.rb │ │ ├── user_symptom_spec.rb │ │ ├── user_treatment_spec.rb │ │ └── weather_spec.rb │ ├── rails_helper.rb │ ├── services │ │ ├── charts_pattern_spec.rb │ │ ├── checkin │ │ │ ├── creator_spec.rb │ │ │ └── updater_spec.rb │ │ ├── collection_retriever_spec.rb │ │ ├── google │ │ │ └── recaptcha_verifier_spec.rb │ │ ├── trackable_creator_spec.rb │ │ └── weather_retriever_spec.rb │ ├── spec_helper.rb │ ├── support │ │ ├── activesupport_timehelpers.rb │ │ ├── db_cleaner.rb │ │ ├── devise.rb │ │ ├── factory_bot.rb │ │ ├── foreign_key_checks.rb │ │ ├── response.rb │ │ ├── shared_examples │ │ │ └── fiveable.rb │ │ └── vcr.rb │ ├── system │ │ ├── signup_spec.rb │ │ └── support │ │ │ ├── capybara_config.rb │ │ │ ├── cuprite_config.rb │ │ │ └── frontend_app.rb │ └── system_spec_helper.rb └── tmp │ └── .keep ├── docker-compose.yml ├── frontend ├── .bowerrc ├── .dockerignore ├── .editorconfig ├── .ember-cli ├── .eslintrc.js ├── .gitignore ├── .npmrc ├── .nvmrc ├── .watchmanconfig ├── Dockerfile ├── README.md ├── app.json ├── app │ ├── adapters │ │ ├── application.js │ │ ├── oracle-request.js │ │ └── reaction.js │ ├── app.js │ ├── authenticators │ │ ├── devise.js │ │ └── facebook.js │ ├── authorizers │ │ └── devise.js │ ├── components │ │ ├── add-reminder.js │ │ ├── add-trackings.js │ │ ├── additional-info.js │ │ ├── at-js-autocomplete.js │ │ ├── birth-date.js │ │ ├── bottom-nav.js │ │ ├── chart-navigation.js │ │ ├── chart-patterns.js │ │ ├── chart │ │ │ ├── g-blank-flat.js │ │ │ ├── g-blank-trackable.js │ │ │ ├── g-flat.js │ │ │ ├── g-hbi.js │ │ │ ├── g-ruler.js │ │ │ ├── g-timeline.js │ │ │ ├── g-trackable.js │ │ │ ├── g-weather.js │ │ │ ├── graphable.js │ │ │ └── resizable.js │ │ ├── checkin-dialog.js │ │ ├── checkin-navigation.js │ │ ├── checkin │ │ │ ├── days-nav.js │ │ │ ├── hbi-step.js │ │ │ ├── health-factors-step.js │ │ │ ├── multi-select-edit.js │ │ │ ├── multi-select-group.js │ │ │ ├── note-edit.js │ │ │ ├── promotion-step.js │ │ │ ├── summary-posts.js │ │ │ ├── summary-step.js │ │ │ ├── trackables-step.js │ │ │ ├── tracked-level.js │ │ │ ├── treatment-taker.js │ │ │ └── weather-step.js │ │ ├── custom-pick-a-time.js │ │ ├── data-export-initiator.js │ │ ├── draggable-dropzone.js │ │ ├── draggable-item.js │ │ ├── emoji-menu.js │ │ ├── emoji-reaction.js │ │ ├── emoji-reactions.js │ │ ├── fb-share-btn.js │ │ ├── form-field.js │ │ ├── form-for.js │ │ ├── health-chart.js │ │ ├── health-dashboard.js │ │ ├── invitation-form.js │ │ ├── join-footer.js │ │ ├── journal-entry.js │ │ ├── journal-list.js │ │ ├── label-switch.js │ │ ├── login-form.js │ │ ├── multi-group.js │ │ ├── nav │ │ │ └── discussions-unread.js │ │ ├── navigation-bar.js │ │ ├── navigation-links.js │ │ ├── notifications-form.js │ │ ├── onboarding-dialog.js │ │ ├── onboarding │ │ │ ├── completed-step.js │ │ │ ├── conditions-step.js │ │ │ ├── demographic-step.js │ │ │ ├── personal-step.js │ │ │ ├── reminder-step.js │ │ │ ├── symptoms-step.js │ │ │ └── treatments-step.js │ │ ├── oracle │ │ │ ├── request-form.js │ │ │ ├── result-item.js │ │ │ ├── result-summary.js │ │ │ └── symptom-multiselect.js │ │ ├── password │ │ │ └── expired-token.js │ │ ├── pattern │ │ │ ├── chart-group.js │ │ │ ├── chart-hover.js │ │ │ ├── chart-item.js │ │ │ ├── chart-legend-item.js │ │ │ ├── create-step.js │ │ │ ├── index-step.js │ │ │ ├── initial-step.js │ │ │ └── svg-initial.js │ │ ├── pip-tag.js │ │ ├── posts │ │ │ ├── activity-notification.js │ │ │ ├── post-comment.js │ │ │ ├── post-topics.js │ │ │ ├── profile-picture.js │ │ │ ├── topic-comment.js │ │ │ └── topic-post.js │ │ ├── power-select │ │ │ ├── dropdown-name-desc.js │ │ │ ├── dropdown-trackable-create.js │ │ │ ├── dropdown-trackable.js │ │ │ └── selected-name.js │ │ ├── profile-form.js │ │ ├── promotion-score.js │ │ ├── reset-password-form.js │ │ ├── save-status.js │ │ ├── scroll-to-anchor.js │ │ ├── select-field.js │ │ ├── share-socials.js │ │ ├── shared-patterns │ │ │ └── dialog.js │ │ ├── signup-form.js │ │ ├── step-controls.js │ │ ├── toggle-logo.js │ │ ├── trackables-select.js │ │ ├── tumblr-share.js │ │ ├── twitter-share-btn.js │ │ └── update-password-form.js │ ├── controllers │ │ ├── .gitkeep │ │ ├── delete.js │ │ ├── notifications.js │ │ ├── oracle │ │ │ └── index.js │ │ ├── posts │ │ │ ├── followings.js │ │ │ ├── index.js │ │ │ ├── new.js │ │ │ ├── profile.js │ │ │ ├── show.js │ │ │ └── topic.js │ │ └── settings.js │ ├── helpers │ │ ├── capitalize.js │ │ ├── checkToday.js │ │ ├── hbi-label.js │ │ ├── includes.js │ │ ├── indexPlusOne.js │ │ ├── pip-label.js │ │ ├── pluralize.js │ │ └── truncate-text.js │ ├── index.html │ ├── instance-initializers │ │ ├── charts-visibility.js │ │ ├── drag-drop-polyfill.js │ │ ├── emojis.js │ │ ├── i18n.js │ │ ├── inject-router-into-components.js │ │ ├── inject-session.js │ │ ├── inject-store-into-components.js │ │ ├── selectable-data.js │ │ └── steps.js │ ├── locales │ │ └── en │ │ │ └── translations.js │ ├── mixins │ │ ├── add-meta-tags.js │ │ ├── authenticated-route-mixin.js │ │ ├── back-navigateable.js │ │ ├── body-formatable.js │ │ ├── chart │ │ │ ├── chart-data-retrieve.js │ │ │ └── dates-retriever.js │ │ ├── checkin-by-date.js │ │ ├── colorable.js │ │ ├── fields-by-units.js │ │ ├── history-trackable.js │ │ ├── navbar-searchable.js │ │ ├── nested-destroyable.js │ │ ├── postable-getable.js │ │ ├── searchable-dropdown.js │ │ ├── searchable.js │ │ ├── step-control.js │ │ ├── toggle-header-logo.js │ │ ├── topicable.js │ │ ├── trackables-from-type.js │ │ ├── typeable.js │ │ ├── unauthenticated-route-mixin.js │ │ ├── update-notifications.js │ │ └── user-nameable.js │ ├── models │ │ ├── chart-list.js │ │ ├── chart.js │ │ ├── checkin-condition.js │ │ ├── checkin-symptom.js │ │ ├── checkin-trackable.js │ │ ├── checkin-treatment.js │ │ ├── checkin.js │ │ ├── comment.js │ │ ├── condition.js │ │ ├── country.js │ │ ├── day-habit.js │ │ ├── dose.js │ │ ├── education-level.js │ │ ├── ethnicity.js │ │ ├── food.js │ │ ├── harvey-bradshaw-index.js │ │ ├── invitation.js │ │ ├── notification.js │ │ ├── oracle-request.js │ │ ├── password.js │ │ ├── pattern.js │ │ ├── post.js │ │ ├── postable.js │ │ ├── profile.js │ │ ├── promotion-rate.js │ │ ├── ranked-enum.js │ │ ├── reactable.js │ │ ├── reaction.js │ │ ├── registration.js │ │ ├── search.js │ │ ├── session.js │ │ ├── sex.js │ │ ├── symptom.js │ │ ├── tag.js │ │ ├── topic-following.js │ │ ├── trackable.js │ │ ├── tracking.js │ │ ├── treatment.js │ │ ├── user.js │ │ └── weather.js │ ├── resolver.js │ ├── router.js │ ├── routes │ │ ├── application.js │ │ ├── chart.js │ │ ├── checkin │ │ │ ├── date.js │ │ │ ├── index.js │ │ │ └── show.js │ │ ├── delete.js │ │ ├── discourse-sign-in.js │ │ ├── index.js │ │ ├── invitation.js │ │ ├── login.js │ │ ├── notifications.js │ │ ├── onboarding.js │ │ ├── oracle.js │ │ ├── oracle │ │ │ ├── index.js │ │ │ └── result.js │ │ ├── password.js │ │ ├── password │ │ │ └── update.js │ │ ├── patterns │ │ │ ├── index.js │ │ │ └── shared.js │ │ ├── posts.js │ │ ├── posts │ │ │ ├── followings.js │ │ │ ├── index.js │ │ │ ├── new.js │ │ │ ├── profile.js │ │ │ ├── show.js │ │ │ └── topic.js │ │ ├── settings.js │ │ ├── signup.js │ │ └── unsubscribe.js │ ├── serializers │ │ ├── chart.js │ │ ├── checkin-treatment.js │ │ ├── checkin.js │ │ ├── comment.js │ │ ├── post.js │ │ └── search.js │ ├── services │ │ ├── ajax.js │ │ ├── chart-journal-switcher.js │ │ ├── chart-selected-dates.js │ │ ├── charts-visibility.js │ │ ├── emojis.js │ │ ├── logo-visiability.js │ │ ├── notification.js │ │ ├── notifications.js │ │ ├── patterns-loading.js │ │ ├── pusher.js │ │ ├── pusher │ │ │ ├── connection.js │ │ │ └── subscription.js │ │ ├── route-history.js │ │ ├── selectable-data.js │ │ ├── session.js │ │ ├── steps.js │ │ └── tracking.js │ ├── session-stores │ │ └── application.js │ ├── styles │ │ ├── _badges.scss │ │ ├── _bottom-nav.scss │ │ ├── _btn-group.scss │ │ ├── _progressbar.scss │ │ ├── _userengage.scss │ │ ├── app.scss │ │ ├── bitters │ │ │ ├── _base.scss │ │ │ ├── _buttons.scss │ │ │ ├── _forms.scss │ │ │ ├── _grid-settings.scss │ │ │ ├── _lists.scss │ │ │ ├── _offsets.scss │ │ │ ├── _tables.scss │ │ │ ├── _typography.scss │ │ │ └── _variables.scss │ │ ├── colorable.scss │ │ ├── components │ │ │ ├── add-trackings.scss │ │ │ ├── additional-info.scss │ │ │ ├── chart-navigation.scss │ │ │ ├── checkin-days-nav.scss │ │ │ ├── checkin-navigation.scss │ │ │ ├── checkin │ │ │ │ ├── hbi-step.scss │ │ │ │ ├── multi-select-group.scss │ │ │ │ ├── summary-step.scss │ │ │ │ ├── trackables-step.scss │ │ │ │ ├── tracked-level.scss │ │ │ │ ├── treatment-taker.scss │ │ │ │ └── weather-step.scss │ │ │ ├── discussions.scss │ │ │ ├── emoji-menu.scss │ │ │ ├── emoji-reactions.scss │ │ │ ├── form-field.scss │ │ │ ├── health-chart.scss │ │ │ ├── invitation-form.scss │ │ │ ├── label-switch.scss │ │ │ ├── login-form.scss │ │ │ ├── navigation-bar.scss │ │ │ ├── reset-password-form.scss │ │ │ ├── save-status.scss │ │ │ ├── signup-form.scss │ │ │ ├── step-controls.scss │ │ │ ├── tags-group.scss │ │ │ └── update-password-form.scss │ │ ├── ember-power-select-search.scss │ │ ├── fonts.scss │ │ ├── global.scss │ │ ├── layout.scss │ │ ├── mixins.scss │ │ ├── pace-theme-minimal.scss │ │ ├── spinner.scss │ │ └── variables.scss │ ├── templates │ │ ├── application-loading.hbs │ │ ├── application.hbs │ │ ├── application │ │ │ ├── footer.hbs │ │ │ ├── header.hbs │ │ │ └── three-bounce-spinner.hbs │ │ ├── chart.hbs │ │ ├── checkin │ │ │ ├── date.hbs │ │ │ └── show.hbs │ │ ├── components │ │ │ ├── add-reminder.hbs │ │ │ ├── add-trackings.hbs │ │ │ ├── additional-info.hbs │ │ │ ├── at-js-autocomplete.hbs │ │ │ ├── birth-date.hbs │ │ │ ├── bottom-nav.hbs │ │ │ ├── chart-navigation.hbs │ │ │ ├── chart-patterns.hbs │ │ │ ├── chart │ │ │ │ ├── g-blank-flat.hbs │ │ │ │ ├── g-blank-trackable.hbs │ │ │ │ ├── g-flat.hbs │ │ │ │ ├── g-hbi.hbs │ │ │ │ ├── g-ruler.hbs │ │ │ │ ├── g-timeline.hbs │ │ │ │ ├── g-trackable.hbs │ │ │ │ └── g-weather.hbs │ │ │ ├── checkin-dialog.hbs │ │ │ ├── checkin-navigation.hbs │ │ │ ├── checkin │ │ │ │ ├── -step-header.hbs │ │ │ │ ├── -trackable-item.hbs │ │ │ │ ├── days-nav.hbs │ │ │ │ ├── hbi-step.hbs │ │ │ │ ├── health-factors-step.hbs │ │ │ │ ├── multi-select-edit.hbs │ │ │ │ ├── multi-select-group.hbs │ │ │ │ ├── note-edit.hbs │ │ │ │ ├── promotion-step.hbs │ │ │ │ ├── summary-posts.hbs │ │ │ │ ├── summary-step.hbs │ │ │ │ ├── trackables-step.hbs │ │ │ │ ├── tracked-level.hbs │ │ │ │ ├── treatment-taker.hbs │ │ │ │ └── weather-step.hbs │ │ │ ├── data-export-initiator.hbs │ │ │ ├── draggable-dropzone.hbs │ │ │ ├── draggable-item.hbs │ │ │ ├── emoji-menu.hbs │ │ │ ├── emoji-reaction.hbs │ │ │ ├── emoji-reactions.hbs │ │ │ ├── fb-share-btn.hbs │ │ │ ├── form-field.hbs │ │ │ ├── form-for.hbs │ │ │ ├── health-chart.hbs │ │ │ ├── health-dashboard.hbs │ │ │ ├── invitation-form.hbs │ │ │ ├── join-footer.hbs │ │ │ ├── journal-entry.hbs │ │ │ ├── journal-list.hbs │ │ │ ├── label-switch.hbs │ │ │ ├── login-form.hbs │ │ │ ├── multi-group.hbs │ │ │ ├── nav │ │ │ │ └── discussions-unread.hbs │ │ │ ├── navigation-bar.hbs │ │ │ ├── navigation-links.hbs │ │ │ ├── notifications-form.hbs │ │ │ ├── onboarding-dialog.hbs │ │ │ ├── onboarding │ │ │ │ ├── completed-step.hbs │ │ │ │ ├── conditions-step.hbs │ │ │ │ ├── demographic-step.hbs │ │ │ │ ├── personal-step.hbs │ │ │ │ ├── reminder-step.hbs │ │ │ │ ├── symptoms-step.hbs │ │ │ │ └── treatments-step.hbs │ │ │ ├── oracle │ │ │ │ ├── request-form.hbs │ │ │ │ ├── result-item.hbs │ │ │ │ ├── result-summary.hbs │ │ │ │ └── symptom-multiselect.hbs │ │ │ ├── password │ │ │ │ └── expired-token.hbs │ │ │ ├── pattern │ │ │ │ ├── chart-group.hbs │ │ │ │ ├── chart-hover.hbs │ │ │ │ ├── chart-legend-item.hbs │ │ │ │ ├── create-step.hbs │ │ │ │ ├── index-step.hbs │ │ │ │ ├── initial-step.hbs │ │ │ │ └── svg-initial.hbs │ │ │ ├── pip-tag.hbs │ │ │ ├── posts │ │ │ │ ├── activity-notification.hbs │ │ │ │ ├── post-comment.hbs │ │ │ │ ├── post-topics.hbs │ │ │ │ ├── profile-picture.hbs │ │ │ │ ├── topic-comment.hbs │ │ │ │ └── topic-post.hbs │ │ │ ├── power-select │ │ │ │ ├── dropdown-name-desc.hbs │ │ │ │ ├── dropdown-trackable-create.hbs │ │ │ │ ├── dropdown-trackable.hbs │ │ │ │ └── selected-name.hbs │ │ │ ├── profile-form.hbs │ │ │ ├── promotion-score.hbs │ │ │ ├── reset-password-form.hbs │ │ │ ├── save-status.hbs │ │ │ ├── scroll-to-anchor.hbs │ │ │ ├── share-socials.hbs │ │ │ ├── shared-patterns │ │ │ │ └── dialog.hbs │ │ │ ├── signup-form.hbs │ │ │ ├── step-controls.hbs │ │ │ ├── toggle-logo.hbs │ │ │ ├── trackables-select.hbs │ │ │ ├── tumblr-share.hbs │ │ │ ├── twitter-share-btn.hbs │ │ │ ├── update-password-form.hbs │ │ │ └── view-remove-tracking.hbs │ │ ├── delete.hbs │ │ ├── invitation.hbs │ │ ├── login.hbs │ │ ├── notifications.hbs │ │ ├── onboarding.hbs │ │ ├── oracle.hbs │ │ ├── oracle │ │ │ ├── index.hbs │ │ │ └── result.hbs │ │ ├── password │ │ │ ├── reset.hbs │ │ │ └── update.hbs │ │ ├── patterns │ │ │ ├── index.hbs │ │ │ └── shared.hbs │ │ ├── posts.hbs │ │ ├── posts │ │ │ ├── followings.hbs │ │ │ ├── index.hbs │ │ │ ├── new.hbs │ │ │ ├── profile.hbs │ │ │ ├── show.hbs │ │ │ └── topic.hbs │ │ ├── privacy-policy.hbs │ │ ├── settings.hbs │ │ ├── signup.hbs │ │ ├── terms-of-service.hbs │ │ └── unsubscribe.hbs │ ├── transforms │ │ ├── birthdate.js │ │ ├── raw.js │ │ └── time-zone-name.js │ └── utils │ │ └── i18n │ │ └── missing-message.js ├── bower.json ├── config │ ├── ember-cli-update.json │ ├── environment.js │ └── targets.js ├── ember-cli-build.js ├── lib │ ├── full-story │ │ ├── index.js │ │ └── package.json │ └── heap-analytics │ │ ├── index.js │ │ └── package.json ├── package-lock.json ├── package.json ├── public │ ├── assets │ │ ├── checkins.svg │ │ ├── crystal-ball.png │ │ ├── emoji │ │ │ ├── IconsetSmiles.png │ │ │ ├── emoji_spritesheet_0.png │ │ │ ├── emoji_spritesheet_1.png │ │ │ ├── emoji_spritesheet_2.png │ │ │ ├── emoji_spritesheet_3.png │ │ │ └── emoji_spritesheet_4.png │ │ ├── empty.svg │ │ ├── fonts │ │ │ ├── proximanova-regular-webfont.eot │ │ │ ├── proximanova-regular-webfont.svg │ │ │ ├── proximanova-regular-webfont.ttf │ │ │ ├── proximanova-regular-webfont.woff │ │ │ ├── proximanovacond-regular-webfont.eot │ │ │ ├── proximanovacond-regular-webfont.svg │ │ │ ├── proximanovacond-regular-webfont.ttf │ │ │ └── proximanovacond-regular-webfont.woff │ │ ├── logo.svg │ │ ├── menu-icon.svg │ │ ├── nav_icons │ │ │ ├── account_2.svg │ │ │ ├── arrow-left.svg │ │ │ ├── arrow-right.svg │ │ │ ├── calendar-icon.svg │ │ │ ├── checkin_2.svg │ │ │ ├── circle.svg │ │ │ ├── close.svg │ │ │ ├── discuss.svg │ │ │ ├── discuss_white.svg │ │ │ ├── discussion-notification.svg │ │ │ ├── discussion-profile.svg │ │ │ ├── discussion-search.svg │ │ │ ├── explore.svg │ │ │ ├── eye.svg │ │ │ ├── history_2.svg │ │ │ ├── history_white.svg │ │ │ ├── left-arrow.svg │ │ │ └── settings-icon.svg │ │ ├── onboarding-success-sm.png │ │ ├── onboarding_success.png │ │ ├── smiley.svg │ │ ├── tag-point.svg │ │ └── weather │ │ │ ├── clear-day.png │ │ │ ├── clear-night.png │ │ │ ├── cloudy.png │ │ │ ├── default.png │ │ │ ├── fog.png │ │ │ ├── partly-cloudy-day.png │ │ │ ├── partly-cloudy-night.png │ │ │ ├── rain.png │ │ │ ├── sleet.png │ │ │ ├── snow.png │ │ │ └── wind.png │ ├── favicon.ico │ └── robots.txt ├── static.json ├── testem.js ├── tests │ ├── helpers │ │ ├── destroy-app.js │ │ ├── module-for-acceptance.js │ │ ├── resolver.js │ │ └── start-app.js │ ├── index.html │ ├── integration │ │ └── components │ │ │ ├── add-reminder-test.js │ │ │ ├── additional-info-test.js │ │ │ ├── at-js-autocomplete-test.js │ │ │ ├── birth-date-test.js │ │ │ ├── checkin-treatment-test.js │ │ │ ├── checkin │ │ │ ├── promotion-step-test.js │ │ │ ├── summary-posts-test.js │ │ │ └── weather-step-test.js │ │ │ ├── custom-pick-a-time-test.js │ │ │ ├── data-export-initiator-test.js │ │ │ ├── emoji-reaction-test.js │ │ │ ├── fb-share-btn-test.js │ │ │ ├── form-for-test.js │ │ │ ├── join-footer-test.js │ │ │ ├── label-switch-test.js │ │ │ ├── nav │ │ │ └── discussions-unread-test.js │ │ │ ├── navigation-bar-test.js │ │ │ ├── navigation-links-test.js │ │ │ ├── notifications-form-test.js │ │ │ ├── onboarding-dialog-test.js │ │ │ ├── onboarding │ │ │ └── reminder-step-test.js │ │ │ ├── posts │ │ │ ├── activity-notification-test.js │ │ │ ├── post-comment-test.js │ │ │ ├── post-topics-test.js │ │ │ ├── profile-picture-test.js │ │ │ ├── topic-comment-test.js │ │ │ └── topic-post-test.js │ │ │ ├── promotion-score-test.js │ │ │ ├── scroll-to-anchor-test.js │ │ │ ├── share-socials-test.js │ │ │ ├── step-controls-test.js │ │ │ ├── toggle-logo-test.js │ │ │ ├── tracked-level-test.js │ │ │ └── twitter-share-btn-test.js │ ├── test-helper.js │ └── unit │ │ ├── adapters │ │ └── reaction-test.js │ │ ├── controllers │ │ ├── notifications-test.js │ │ ├── oracle │ │ │ └── index-test.js │ │ ├── posts │ │ │ ├── followings-test.js │ │ │ ├── index-test.js │ │ │ ├── new-test.js │ │ │ ├── profile-test.js │ │ │ ├── show-test.js │ │ │ └── topic-test.js │ │ └── settings-test.js │ │ ├── helpers │ │ └── includes-test.js │ │ ├── instance-initializers │ │ └── emojis-test.js │ │ ├── mixins │ │ ├── add-meta-tags-test.js │ │ ├── back-navigateable-test.js │ │ ├── body-formatable-test.js │ │ ├── fields-by-units-test.js │ │ ├── history-trackable-test.js │ │ ├── navbar-searchable-test.js │ │ ├── postable-getable-test.js │ │ ├── toggle-header-logo-test.js │ │ ├── topicable-test.js │ │ ├── typeable-test.js │ │ ├── update-notifications-test.js │ │ └── user-nameable-test.js │ │ ├── models │ │ ├── chart-list-test.js │ │ ├── comment-test.js │ │ ├── food-test.js │ │ ├── harvey-bradshaw-index-test.js │ │ ├── notification-test.js │ │ ├── oracle-request-test.js │ │ ├── pattern-test.js │ │ ├── post-test.js │ │ ├── postable-test.js │ │ ├── reactable-test.js │ │ ├── reaction-test.js │ │ ├── session-test.js │ │ ├── topic-following-test.js │ │ ├── user-test.js │ │ └── weather-test.js │ │ ├── routes │ │ ├── notifications-test.js │ │ ├── oracle-test.js │ │ ├── oracle │ │ │ ├── index-test.js │ │ │ └── result-test.js │ │ ├── posts-test.js │ │ ├── posts │ │ │ ├── followings-test.js │ │ │ ├── index-test.js │ │ │ ├── new-test.js │ │ │ ├── profile-test.js │ │ │ ├── show-test.js │ │ │ └── topic-test.js │ │ └── settings-test.js │ │ ├── serializers │ │ └── post-test.js │ │ ├── services │ │ ├── ajax-test.js │ │ ├── emojis-test.js │ │ ├── logo-visiability-test.js │ │ ├── notifications-test.js │ │ └── route-history-test.js │ │ └── transforms │ │ ├── raw-test.js │ │ └── time-zone-name-test.js └── vendor │ └── .gitkeep ├── impact.md ├── native ├── .dockerignore ├── .eslintrc.js ├── .gitignore ├── .nvmrc ├── AppEntry.js ├── Dockerfile ├── app.json ├── assets │ ├── adaptive-icon.png │ ├── favicon.png │ ├── icon.png │ └── splash.png ├── babel.config.js ├── package-lock.json ├── package.json ├── src │ ├── App.test.tsx │ ├── App.tsx │ ├── Theme.ts │ ├── components │ │ ├── BackButton.tsx │ │ ├── Background.tsx │ │ ├── Button.tsx │ │ ├── Card.tsx │ │ ├── Footer.tsx │ │ ├── Header.tsx │ │ ├── Layout.tsx │ │ ├── Link.tsx │ │ └── TextInput.tsx │ ├── helpers │ │ ├── emailValidator.ts │ │ ├── passwordValidator.ts │ │ └── usernameValidator.ts │ └── screens │ │ ├── CreateAccountScreen.tsx │ │ ├── Dashboard.tsx │ │ ├── LoginScreen.tsx │ │ └── ResetPasswordScreen.tsx ├── tsconfig.json └── webpack.config.js └── script ├── backend ├── ember ├── frontend └── npm /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | 8 | - package-ecosystem: "bundler" 9 | directory: "/backend" 10 | schedule: 11 | interval: "weekly" 12 | 13 | - package-ecosystem: "npm" 14 | directory: "/frontend" 15 | schedule: 16 | interval: "weekly" 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | npm-debug.log 3 | 4 | backend/dump.rdb 5 | backend/dump 6 | 7 | dump.rdb 8 | .rbenv-gemsets 9 | 10 | .idea/* 11 | .bundle 12 | frontend/.env 13 | 14 | .DS_Store 15 | 16 | TODO.md 17 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | flaredown 2 | 3 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.3 2 | -------------------------------------------------------------------------------- /.tool-versions: -------------------------------------------------------------------------------- 1 | nodejs 12.22.6 2 | ruby 3.2.3 3 | postgres 12.8 4 | mongodb 4.4.9 5 | redis 6.2.3 6 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /backend/.pryrc: -------------------------------------------------------------------------------- 1 | Pry.config.pager = false 2 | 3 | Pry.config.color = true 4 | 5 | if defined?(Rails) 6 | Pry.config.prompt_name = "#{Rails.application.class.module_parent_name.downcase.green}/#{Rails.env.red}" 7 | end 8 | -------------------------------------------------------------------------------- /backend/.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --tag ~type:system 3 | -------------------------------------------------------------------------------- /backend/.ruby-version: -------------------------------------------------------------------------------- 1 | ../.ruby-version -------------------------------------------------------------------------------- /backend/.tool-versions: -------------------------------------------------------------------------------- 1 | ../.tool-versions -------------------------------------------------------------------------------- /backend/Procfile: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | worker: bundle exec sidekiq -C config/sidekiq.yml 3 | -------------------------------------------------------------------------------- /backend/Procfile.local: -------------------------------------------------------------------------------- 1 | web: bundle exec puma -C config/puma.rb 2 | worker: bundle exec sidekiq -C config/sidekiq.yml 3 | -------------------------------------------------------------------------------- /backend/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path("../config/application", __FILE__) 5 | Rails.application.load_tasks 6 | -------------------------------------------------------------------------------- /backend/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | //= link_tree ../images 2 | //= link_directory ../javascripts .js 3 | //= link_directory ../stylesheets .css -------------------------------------------------------------------------------- /backend/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/app/assets/images/.keep -------------------------------------------------------------------------------- /backend/app/assets/javascripts/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/app/assets/javascripts/.gitkeep -------------------------------------------------------------------------------- /backend/app/assets/stylesheets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/app/assets/stylesheets/.gitkeep -------------------------------------------------------------------------------- /backend/app/controllers/api/v1/chart_lists_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class ChartListsController < ApplicationController 4 | def show 5 | render json: ChartListService.new(current_user: current_user).as_json 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/controllers/api/v1/data_export_schedules_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class DataExportSchedulesController < ApplicationController 4 | def create 5 | DataExportJob.perform_later(current_user.id) 6 | 7 | head :created 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/controllers/api/v1/discourses_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class DiscoursesController < ApplicationController 4 | def create 5 | render json: {url: DiscourseClient.new(current_user, params).generate_url} 6 | end 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/controllers/api/v1/pushers_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class PushersController < ApplicationController 4 | def create 5 | render json: Flaredown.pusher.authenticate!(current_user, socket_id) 6 | rescue 7 | render json: {errors: "Bad authentication"}, status: "403" 8 | end 9 | 10 | private 11 | 12 | def socket_id 13 | params.require(:socket_id) 14 | end 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /backend/app/controllers/api/v1/registrations_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class RegistrationsController < ApplicationController 4 | skip_before_action :authenticate_user! 5 | 6 | def create 7 | render json: Registration.create!(params) 8 | end 9 | 10 | def destroy 11 | render json: Registration.delete!(params) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/controllers/api/v1/users_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class UsersController < ApplicationController 4 | load_and_authorize_resource 5 | 6 | def show 7 | render json: @user 8 | end 9 | 10 | def update 11 | @user.update!(user_params) 12 | 13 | render json: @user 14 | end 15 | 16 | private 17 | 18 | def user_params 19 | params.require(:user).permit(:email) 20 | end 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /backend/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /backend/app/extenders/post_extender.rb: -------------------------------------------------------------------------------- 1 | module PostExtender 2 | attr_reader :priority 3 | 4 | def frequency_topic_priority(priority) 5 | @priority = priority 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/jobs/application_job.rb: -------------------------------------------------------------------------------- 1 | class ApplicationJob < ActiveJob::Base 2 | end 3 | -------------------------------------------------------------------------------- /backend/app/jobs/email_reject_job.rb: -------------------------------------------------------------------------------- 1 | class EmailRejectJob 2 | include Sidekiq::Worker 3 | 4 | def perform(recipients_hash) 5 | User.where(email: recipients_hash.values.first).includes(:profile).map do |user| 6 | user.profile.update_column(:rejected_type, recipients_hash.keys.first.to_s) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/jobs/hello_world_job.rb: -------------------------------------------------------------------------------- 1 | class HelloWorldJob < ActiveJob::Base 2 | queue_as :default 3 | 4 | def perform(*_args) 5 | Rails.logger.debug("Hello World".green) 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/jobs/merge_trackables/remove_duplicates.rb: -------------------------------------------------------------------------------- 1 | class MergeTrackables::RemoveDuplicates 2 | include Sidekiq::Worker 3 | 4 | def perform(trackable_type, rest_ids) 5 | trackable_class = trackable_type.capitalize.constantize 6 | return unless trackable_class 7 | 8 | trackable_class.where(id: rest_ids).map(&:destroy) 9 | p "FINISH!!!!" 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/jobs/merge_trackables/trackings.rb: -------------------------------------------------------------------------------- 1 | class MergeTrackables::Trackings 2 | include Sidekiq::Worker 3 | 4 | def perform(trackable_type, parent_id, rest_ids) 5 | Tracking.where(trackable_id: rest_ids, trackable_type: trackable_type.camelcase).map do |tracking| 6 | tracking.update(trackable_id: parent_id) 7 | end 8 | 9 | p "PERFORM MergeTrackables::TopicFollowing" 10 | 11 | MergeTrackables::TopicFollowing.perform_async(trackable_type, parent_id, rest_ids) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/app/jobs/notification_dispatcher.rb: -------------------------------------------------------------------------------- 1 | class NotificationDispatcher 2 | include Sidekiq::Worker 3 | 4 | def perform 5 | Notification.distinct(:encrypted_notify_user_id).each do |encrypted_id| 6 | GroupNotifiersPerUser.perform_async(encrypted_id) 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/jobs/position_reference_job.rb: -------------------------------------------------------------------------------- 1 | class PositionReferenceJob 2 | include Sidekiq::Worker 3 | 4 | def perform(object_class, objec_id, postal_code) 5 | object = object_class.constantize.find_by(id: objec_id) 6 | position = Position.find_or_create_by(postal_code: postal_code) 7 | 8 | object.update(position_id: position.id) if position.persisted? 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/app/jobs/update_post_counters_job.rb: -------------------------------------------------------------------------------- 1 | class UpdatePostCountersJob 2 | include Sidekiq::Worker 3 | 4 | def perform(params) 5 | parent_type = params["parent_type"] 6 | return unless parent_type == "Post" 7 | 8 | post = Post.find_by(_id: params["parent_id"], _type: parent_type) 9 | return unless post 10 | 11 | post&.update_counters 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | default from: Rails.application.secrets.smtp_email_from 3 | 4 | REGEXP = /\A\s*([-\p{L}\d+._]{1,64})@((?:[-\p{L}\d]+\.)+\p{L}{2,})\s*\z/i 5 | 6 | def valid_email?(email) 7 | email =~ REGEXP 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/mailers/promotion_rate/low_rate_mailer.rb: -------------------------------------------------------------------------------- 1 | class PromotionRate::LowRateMailer < ApplicationMailer 2 | layout "mailer_layout" 3 | 4 | def show(email, objects, start_date, end_date) 5 | @email = email 6 | @objects = objects 7 | @start_date = start_date 8 | @end_date = end_date 9 | 10 | mail(to: @email, subject: I18n.t("promotion_rate.low_rate.subject")) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/mailers/promotion_rate/statistic_mailer.rb: -------------------------------------------------------------------------------- 1 | class PromotionRate::StatisticMailer < ApplicationMailer 2 | layout "mailer_layout" 3 | 4 | def show(email, objects, start_date, end_date) 5 | @email = email 6 | @objects = objects 7 | @start_date = start_date 8 | @end_date = end_date 9 | 10 | mail(to: @email, subject: I18n.t("promotion_rate.statistic.subject")) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/mailers/user_data_mailer.rb: -------------------------------------------------------------------------------- 1 | class UserDataMailer < ApplicationMailer 2 | def trackings_csv(email, csv_data) 3 | attachments["data.csv"] = csv_data 4 | 5 | mail to: email 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/models/application_record.rb: -------------------------------------------------------------------------------- 1 | class ApplicationRecord < ActiveRecord::Base 2 | self.abstract_class = true 3 | end 4 | -------------------------------------------------------------------------------- /backend/app/models/checkin/fiveable.rb: -------------------------------------------------------------------------------- 1 | module Checkin::Fiveable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | field :value, type: Integer 6 | validates :value, inclusion: {in: (0..4), allow_blank: true} 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/app/models/checkin/trackable.rb: -------------------------------------------------------------------------------- 1 | module Checkin::Trackable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | # 6 | # Fields 7 | # 8 | field :position, type: Integer 9 | field :color_id, type: String 10 | 11 | # 12 | # Relations 13 | # 14 | belongs_to :checkin, index: true 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /backend/app/models/concerns/authenticatable.rb: -------------------------------------------------------------------------------- 1 | module Authenticatable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | # 6 | # Devise 7 | # 8 | devise :database_authenticatable, 9 | :rememberable, 10 | :recoverable, 11 | :trackable, 12 | :validatable, 13 | :invitable, 14 | :omniauthable 15 | 16 | # 17 | # Validates 18 | # 19 | validates :password, confirmation: true 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /backend/app/models/concerns/usernameable.rb: -------------------------------------------------------------------------------- 1 | module Usernameable 2 | def user_name 3 | Profile.select(:screen_name).find_by!(user_id: SymmetricEncryption.decrypt(encrypted_user_id)).screen_name 4 | rescue SymmetricEncryption::CipherError 5 | "" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/models/day_habit.rb: -------------------------------------------------------------------------------- 1 | class DayHabit < RankedEnum 2 | class << self 3 | def all_ids 4 | %w[lying_down sitting_down on_feet driving working_with_hands] 5 | end 6 | end 7 | 8 | def name 9 | I18n.t "#{key}.#{id}.name" 10 | end 11 | 12 | def description 13 | I18n.t "#{key}.#{id}.description" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/models/dose.rb: -------------------------------------------------------------------------------- 1 | class Dose 2 | include ActiveModel::Serialization 3 | include ActiveModel::Model 4 | 5 | attr_accessor :name 6 | 7 | def id 8 | name.parameterize 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/app/models/education_level.rb: -------------------------------------------------------------------------------- 1 | class EducationLevel < RankedEnum 2 | class << self 3 | def all_ids 4 | %w[less_than_hi_school hi_school college_degree bachelors_degree advanced_degree] 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/models/ethnicity.rb: -------------------------------------------------------------------------------- 1 | class Ethnicity < RankedEnum 2 | class << self 3 | def all_ids 4 | %w[ latino white east_asian south_asian black oceanian 5 | middle_eastern native_american african other not_sure ] 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/app/models/feedback.rb: -------------------------------------------------------------------------------- 1 | class Feedback 2 | include Mongoid::Document 3 | include Mongoid::Timestamps 4 | 5 | # 6 | # Fields 7 | # 8 | field :email, type: String 9 | field :delete_reason, type: String 10 | 11 | # 12 | # Indexes 13 | # 14 | index(date: 1, encrypted_user_id: 1) 15 | 16 | # 17 | # Validations 18 | # 19 | validates :email, :delete_reason, presence: true 20 | end 21 | -------------------------------------------------------------------------------- /backend/app/models/postable.rb: -------------------------------------------------------------------------------- 1 | class Postable 2 | include Mongoid::Document 3 | end 4 | -------------------------------------------------------------------------------- /backend/app/models/search/for_food.rb: -------------------------------------------------------------------------------- 1 | class Search::ForFood < ::Search 2 | validates :query, presence: true 3 | 4 | protected 5 | 6 | def find_by_query 7 | Food.fts(query[:name], MAX_ROWS, user.id) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/models/search/for_topic.rb: -------------------------------------------------------------------------------- 1 | class Search::ForTopic < ::Search 2 | alias_method :super_query, :find_by_query 3 | 4 | protected 5 | 6 | def find_by_query 7 | (tags + symptoms + conditions + treatments).sort { |a, b| a.name.underscore <=> b.name.underscore } 8 | end 9 | 10 | private 11 | 12 | %w[tag symptom condition treatment].each do |trackable| 13 | define_method trackable.pluralize do 14 | @resource = trackable 15 | 16 | super_query 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /backend/app/models/sex.rb: -------------------------------------------------------------------------------- 1 | class Sex < RankedEnum 2 | class << self 3 | def all_ids 4 | %w[male female other doesnt_say] 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/models/tag.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: tags 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # 9 | 10 | class Tag < ActiveRecord::Base 11 | has_many :tag_translations, class_name: "Tag::Translation" 12 | 13 | # 14 | # Localized attributes 15 | # 16 | translates :name 17 | end 18 | -------------------------------------------------------------------------------- /backend/app/models/topic_following.rb: -------------------------------------------------------------------------------- 1 | class TopicFollowing 2 | include Topicable 3 | 4 | def add_topic(key, value) 5 | return if send(key).include?(value) 6 | 7 | send(key) << value 8 | 9 | save 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/models/user_food.rb: -------------------------------------------------------------------------------- 1 | class UserFood < ActiveRecord::Base 2 | # 3 | # Associations 4 | # 5 | belongs_to :user 6 | belongs_to :food 7 | 8 | # 9 | # Validations 10 | # 11 | validates :user, :food, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/models/user_tag.rb: -------------------------------------------------------------------------------- 1 | class UserTag < ActiveRecord::Base 2 | # 3 | # Associations 4 | # 5 | belongs_to :user 6 | belongs_to :tag 7 | 8 | # 9 | # Validations 10 | # 11 | validates :user, :tag, presence: true 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/models/weather.rb: -------------------------------------------------------------------------------- 1 | class Weather < ActiveRecord::Base 2 | validates :date, uniqueness: {scope: :position_id} 3 | # NOTE: if we want to enforce presence, modify spec factory instead 4 | belongs_to :position, optional: true 5 | end 6 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/chart_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class ChartSerializer < ApplicationSerializer 4 | attributes :id, 5 | :start_at, 6 | :end_at 7 | 8 | has_many :checkins, embed: :ids, embed_in_root: true 9 | has_many :trackables, embed: :objects 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/checkin_condition_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class CheckinConditionSerializer < CheckinTrackableSerializer 4 | attributes :condition_id 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/checkin_symptom_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class CheckinSymptomSerializer < CheckinTrackableSerializer 4 | attributes :symptom_id 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/checkin_trackable_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class CheckinTrackableSerializer < ApplicationSerializer 4 | attributes :checkin_id, :value, :color_id, :position 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/checkin_treatment_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class CheckinTreatmentSerializer < CheckinTrackableSerializer 4 | attributes :treatment_id, :is_taken 5 | has_one :dose, embed: :object 6 | 7 | private 8 | 9 | def dose 10 | ::Dose.new(name: object.value) if object.value.present? 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/comment_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class CommentSerializer < ApplicationSerializer 4 | include Concerns::Notificatable 5 | include Concerns::ReactionRelatable 6 | 7 | attributes :post_id, :body, :user_name, :postable_id, :type 8 | 9 | def type 10 | "comment" 11 | end 12 | 13 | def postable_id 14 | :fake 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/concerns.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | module Concerns 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/concerns/notificatable.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | module Concerns 4 | module Notificatable 5 | extend ActiveSupport::Concern 6 | 7 | included do 8 | attributes :notifications 9 | end 10 | 11 | def notifications 12 | return {} unless current_user 13 | object.notifications.where(encrypted_notify_user_id: current_user.encrypted_id).count_by_types 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/country_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class CountrySerializer < ApplicationSerializer 4 | attributes :id, :name 5 | 6 | def id 7 | object.alpha2 8 | end 9 | 10 | def name 11 | object.translation(I18n.locale.to_s) 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/day_habit_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class DayHabitSerializer < RankedEnumSerializer 4 | attributes :description 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/dose_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class DoseSerializer < ApplicationSerializer 4 | include SearchableSerializer 5 | 6 | attributes :id, :name 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/education_level_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class EducationLevelSerializer < RankedEnumSerializer 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/ethnicity_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class EthnicitySerializer < RankedEnumSerializer 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/food_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class FoodSerializer < ApplicationSerializer 4 | include SearchableSerializer 5 | 6 | attributes :id, :name 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/harvey_bradshaw_index_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class HarveyBradshawIndexSerializer < ApplicationSerializer 4 | attributes :id, :abdominal_mass, :abdominal_pain, :abscess, :anal_fissure, :aphthous_ulcers, :arthralgia, :score, 5 | :erythema_nodosum, :new_fistula, :pyoderma_gangrenosum, :stools, :uveitis, :well_being, :checkin_id 6 | end 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/invitation_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class InvitationSerializer < ApplicationSerializer 4 | attributes :id, :email 5 | 6 | has_one :user, embed_in_root: true 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/oracle_request_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class OracleRequestSerializer < ApplicationSerializer 4 | attributes :id, :age, :sex_id, :symptom_ids, :responce, :can_edit 5 | 6 | has_one :sex, embed_in_root: true 7 | has_many :symptoms, embed_in_root: true 8 | 9 | def can_edit 10 | object.can_edit?(scope) 11 | end 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/oracle_request_with_token_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class OracleRequestWithTokenSerializer < OracleRequestSerializer 4 | self.root = :oracle_request 5 | 6 | attributes :token 7 | 8 | def can_edit 9 | true 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/pattern_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class PatternSerializer < ApplicationSerializer 4 | attributes :id, :start_at, :end_at, :name, :includes, :author_name 5 | 6 | def author_name 7 | object.author.screen_name 8 | end 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/promotion_rate_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class PromotionRateSerializer < ApplicationSerializer 4 | attributes :id, :score, :feedback, :checkin_id 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/ranked_enum_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class RankedEnumSerializer < ApplicationSerializer 4 | attributes :id, :name, :rank 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/registration_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class RegistrationSerializer < ApplicationSerializer 4 | has_one :user, embed_in_root: true 5 | 6 | private 7 | 8 | def id 9 | object.user.id 10 | end 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/search_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class SearchSerializer < ApplicationSerializer 4 | attributes :id 5 | 6 | has_many :searchables, embed: :objects 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/searchable_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | module SearchableSerializer 4 | extend ActiveSupport::Concern 5 | 6 | included do 7 | attributes :type 8 | end 9 | 10 | def type 11 | object.class.name.demodulize.downcase.dasherize 12 | end 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/sex_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class SexSerializer < RankedEnumSerializer 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/topic_following_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class TopicFollowingSerializer < ApplicationSerializer 4 | include Concerns::TopicSerializable 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/api/v1/weather_serializer.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | class WeatherSerializer < ApplicationSerializer 4 | attributes :id, :humidity, :icon, :precip_intensity, :pressure, :summary, :temperature_max, :temperature_min 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/app/serializers/application_serializer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationSerializer < ActiveModel::Serializer 2 | include Rails.application.routes.url_helpers 3 | 4 | attributes :id, :created_at, :updated_at 5 | 6 | alias_method :current_user, :scope 7 | 8 | def id 9 | object.try :id 10 | end 11 | 12 | def created_at 13 | object.try :created_at 14 | end 15 | 16 | def updated_at 17 | object.try :updated_at 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /backend/app/services/additional_posts.rb: -------------------------------------------------------------------------------- 1 | class AdditionalPosts 2 | protected 3 | 4 | def current_ability 5 | @current_ability ||= Ability.new(user) 6 | end 7 | 8 | def add_last_new_posts(number, followed_ids) 9 | Post.where(_type: "Post") 10 | .not_in(_id: followed_ids) 11 | .order(created_at: :desc) 12 | .to_a 13 | .first(number) 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /backend/app/views/devise/mailer/reset_password_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Someone has requested a password reset for your account on Flaredown.com. You can do this through the link below.

4 | 5 |

<%= link_to 'Change my password', "#{ENV['BASE_URL']}/password/#{@token}" %>

6 | 7 |

If you didn't request this, please ignore this email.

8 |

Don't worry, your password won't change unless you choose to use the link above.

9 | -------------------------------------------------------------------------------- /backend/app/views/layouts/mailer_layout.html.erb: -------------------------------------------------------------------------------- 1 | <%= yield :body %> 2 | -------------------------------------------------------------------------------- /backend/app/views/promotion_rate/low_rate_mailer/show.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :body do %> 2 |

Data for current range of dates: <%= "#{@start_date} - #{@end_date}" %>

3 | 4 | <% @objects.sort_by {|item| item["_id"]}.each do |obj| %> 5 |

Score: <%= obj["score"] %> 6 | Feedback: <%= obj["feedback"] %> 7 | Date: <%= obj["date"].to_date %> 8 |

9 | <% end %> 10 | <% end %> 11 | -------------------------------------------------------------------------------- /backend/app/views/promotion_rate/statistic_mailer/show.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :body do %> 2 |

Data for current range of dates: <%= "#{@start_date} - #{@end_date}" %>

3 | 4 | <% @objects.sort_by {|item| item["_id"]}.each do |obj| %> 5 |

Score: <%= obj["_id"] %> 6 | Amount: <%= obj["count"] %> 7 |

8 | <% end %> 9 | <% end %> 10 | -------------------------------------------------------------------------------- /backend/app/views/top_posts_mailer/notify.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for :body do %> 2 |

Top Post for you this week

3 | 4 | <% if @top_posts.any? %> 5 | <% @top_posts.each do |post| %> 6 |

<%= post.title %>

7 |

<%= post.body %>

8 | <% end %> 9 | <% else %> 10 | There is no top posts for now 11 | <% end %> 12 | 13 |

You can <%= link_to 'unsubscribe', @unsubscribe_link %> from weekly top posts notifications

14 | <% end %> 15 | -------------------------------------------------------------------------------- /backend/app/views/user_data_mailer/trackings_csv.text.erb: -------------------------------------------------------------------------------- 1 | You'll find your Flaredown data attached in .CSV format. We hope it helps! 2 | 3 | - The Flaredown Team 4 | -------------------------------------------------------------------------------- /backend/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__) 3 | load Gem.bin_path("bundler", "bundle") 4 | -------------------------------------------------------------------------------- /backend/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | if ENV["RAILS_ENV"] == "test" 3 | require "simplecov" 4 | SimpleCov.start "rails" 5 | puts "required simplecov" 6 | end 7 | APP_PATH = File.expand_path("../config/application", __dir__) 8 | require_relative "../config/boot" 9 | require "rails/commands" 10 | -------------------------------------------------------------------------------- /backend/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /backend/bin/rspec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | # 3 | # This file was generated by Bundler. 4 | # 5 | # The application 'rspec' is installed as part of a gem, and 6 | # this file is here to facilitate running it. 7 | # 8 | 9 | require "pathname" 10 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 11 | Pathname.new(__FILE__).realpath) 12 | 13 | require "rubygems" 14 | require "bundler/setup" 15 | 16 | load Gem.bin_path("rspec-core", "rspec") 17 | -------------------------------------------------------------------------------- /backend/bin/system_spec: -------------------------------------------------------------------------------- 1 | # Eg: 2 | # bin/system_spec 3 | # bin/system_spec --format doc spec/system/signup_spec.rb 4 | bundle exec rspec --tag type:system "$@" 5 | -------------------------------------------------------------------------------- /backend/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path("../config/environment", __FILE__) 4 | 5 | run Rails.application 6 | -------------------------------------------------------------------------------- /backend/config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /backend/config/cronotab.rb: -------------------------------------------------------------------------------- 1 | require "rake" 2 | 3 | Rails.app_class.load_tasks 4 | 5 | Crono.perform(NotificationDispatcher).every(3.minutes) 6 | -------------------------------------------------------------------------------- /backend/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /backend/config/initializers/action_mailer.rb: -------------------------------------------------------------------------------- 1 | ActionMailer::Base.default_url_options = {host: ENV["BASE_URL"]} 2 | 3 | ActionMailer::Base.smtp_settings = { 4 | port: ENV["SMTP_PORT"], 5 | address: ENV["SMTP_ADDRESS"], 6 | user_name: ENV["SMTP_USER"], 7 | password: ENV["SMTP_PASS"], 8 | domain: ENV["SMTP_DOMAIN"], 9 | authentication: :login 10 | } 11 | -------------------------------------------------------------------------------- /backend/config/initializers/active_model_serializers.rb: -------------------------------------------------------------------------------- 1 | ActiveModel::Serializer.setup do |config| 2 | config.embed = :ids 3 | config.embed_in_root = false 4 | end 5 | -------------------------------------------------------------------------------- /backend/config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ApplicationController.renderer.defaults.merge!( 4 | # http_host: 'example.org', 5 | # https: false 6 | # ) 7 | -------------------------------------------------------------------------------- /backend/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /backend/config/initializers/bugsnag.rb: -------------------------------------------------------------------------------- 1 | Bugsnag.configure do |config| 2 | config.api_key = ENV["BUGSNAG_API_KEY"] 3 | config.release_stage = ENV["BUGSNAG_RELEASE_STAGE"] || ENV["RAILS_ENV"] 4 | end 5 | -------------------------------------------------------------------------------- /backend/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. 4 | # Use this to limit dissemination of sensitive information. 5 | # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. 6 | Rails.application.config.filter_parameters += [ 7 | :password, :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn 8 | ] 9 | -------------------------------------------------------------------------------- /backend/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /backend/config/initializers/mongoid.rb: -------------------------------------------------------------------------------- 1 | Mongoid.configure do |config| 2 | config.load_defaults 8.1 3 | end 4 | 5 | Mongoid::Document.send(:include, ActiveModel::SerializerSupport) 6 | Mongoid::Criteria.delegate(:active_model_serializer, to: :to_a) 7 | 8 | module BSON 9 | class ObjectId 10 | alias_method :to_json, :to_s 11 | alias_method :as_json, :to_s 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/config/initializers/preview_interceptors.rb: -------------------------------------------------------------------------------- 1 | ActionMailer::Base.register_preview_interceptor(ActionMailer::InlinePreviewInterceptor) 2 | -------------------------------------------------------------------------------- /backend/config/initializers/rack_timeout.rb: -------------------------------------------------------------------------------- 1 | # Rack::Timeout.service_timeout = 25 # seconds 2 | -------------------------------------------------------------------------------- /backend/config/initializers/sidekiq.rb: -------------------------------------------------------------------------------- 1 | Sidekiq.configure_server do |config| 2 | config.redis = {url: Flaredown.config.redis_url, size: 4, db: ENV["REDIS_DB"]} 3 | end 4 | 5 | Sidekiq.configure_client do |config| 6 | config.redis = {url: Flaredown.config.redis_url, size: 1, db: ENV["REDIS_DB"]} 7 | end 8 | -------------------------------------------------------------------------------- /backend/config/initializers/tomorrowio_rb.rb: -------------------------------------------------------------------------------- 1 | Tomorrowiorb.api_key = Rails.application.secrets.tomorrow_io_key 2 | -------------------------------------------------------------------------------- /backend/config/locales/it.yml: -------------------------------------------------------------------------------- 1 | it: 2 | sex: 3 | male: "Maschio" 4 | female: "Femmina" 5 | other: "Altro" 6 | doesnt_say: "Preferisco non dirlo" 7 | -------------------------------------------------------------------------------- /backend/config/sidekiq.yml: -------------------------------------------------------------------------------- 1 | default: &default 2 | :verbose: false 3 | :concurrency: 2 4 | 5 | 6 | # Set timeout to 8 on Heroku, longer if you manage your own systems. 7 | :timeout: 30 8 | 9 | :pidfile: tmp/sidekiq.pid 10 | :queues: 11 | - default 12 | - mailers 13 | 14 | development: 15 | <<: *default 16 | :verbose: true 17 | 18 | test: 19 | <<: *default 20 | 21 | staging: 22 | <<: *default 23 | 24 | production: 25 | <<: *default 26 | -------------------------------------------------------------------------------- /backend/db/migrate/20160101154821_create_extensions.rb: -------------------------------------------------------------------------------- 1 | class CreateExtensions < ActiveRecord::Migration 2 | def change 3 | enable_extension "pg_trgm" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20160119185831_create_profiles.rb: -------------------------------------------------------------------------------- 1 | class CreateProfiles < ActiveRecord::Migration 2 | def change 3 | create_table :profiles do |t| 4 | t.belongs_to :user, index: true, foreign_key: true 5 | t.string :country_id 6 | t.date :birth_date 7 | t.string :sex_id 8 | t.string :onboarding_step_id 9 | 10 | t.timestamps null: false 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/db/migrate/20160128112500_create_conditions.rb: -------------------------------------------------------------------------------- 1 | class CreateConditions < ActiveRecord::Migration 2 | def up 3 | create_table :conditions do |t| 4 | t.boolean :global, default: true 5 | t.timestamps null: false 6 | end 7 | Condition.create_translation_table! name: :string 8 | end 9 | 10 | def down 11 | drop_table :conditions 12 | Condition.drop_translation_table! 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/db/migrate/20160128114341_create_user_conditions.rb: -------------------------------------------------------------------------------- 1 | class CreateUserConditions < ActiveRecord::Migration 2 | def change 3 | create_table :user_conditions do |t| 4 | t.belongs_to :user, index: true, foreign_key: true 5 | t.belongs_to :condition, index: true, foreign_key: true 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20160128191053_create_symptoms.rb: -------------------------------------------------------------------------------- 1 | class CreateSymptoms < ActiveRecord::Migration 2 | def up 3 | create_table :symptoms do |t| 4 | t.boolean :global, default: true 5 | t.timestamps null: false 6 | end 7 | Symptom.create_translation_table! name: :string 8 | end 9 | 10 | def down 11 | drop_table :symptoms 12 | Symptom.drop_translation_table! 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/db/migrate/20160128191329_create_user_symptoms.rb: -------------------------------------------------------------------------------- 1 | class CreateUserSymptoms < ActiveRecord::Migration 2 | def change 3 | create_table :user_symptoms do |t| 4 | t.belongs_to :user, index: true, foreign_key: true 5 | t.belongs_to :symptom, index: true, foreign_key: true 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20160129063945_create_treatments.rb: -------------------------------------------------------------------------------- 1 | class CreateTreatments < ActiveRecord::Migration 2 | def up 3 | create_table :treatments do |t| 4 | t.boolean :global, default: true 5 | t.timestamps null: false 6 | end 7 | Treatment.create_translation_table! name: :string 8 | end 9 | 10 | def down 11 | drop_table :treatments 12 | Treatment.drop_translation_table! 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/db/migrate/20160129064538_create_user_treatments.rb: -------------------------------------------------------------------------------- 1 | class CreateUserTreatments < ActiveRecord::Migration 2 | def change 3 | create_table :user_treatments do |t| 4 | t.belongs_to :user, index: true, foreign_key: true 5 | t.belongs_to :treatment, index: true, foreign_key: true 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20160211105611_create_tags.rb: -------------------------------------------------------------------------------- 1 | class CreateTags < ActiveRecord::Migration 2 | def up 3 | create_table :tags do |t| 4 | t.timestamps null: false 5 | end 6 | Tag.create_translation_table! name: :string 7 | end 8 | 9 | def down 10 | drop_table :tags 11 | Tag.drop_translation_table! 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/db/migrate/20160224141256_add_demographics_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddDemographicsToProfiles < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :ethnicity_ids_string, :string 4 | add_column :profiles, :day_habit_id, :string 5 | add_column :profiles, :education_level_id, :string 6 | add_column :profiles, :day_walking_hours, :integer 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20160404073700_enable_hstore_extension.rb: -------------------------------------------------------------------------------- 1 | class EnableHstoreExtension < ActiveRecord::Migration 2 | def change 3 | enable_extension "hstore" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20160404073731_add_most_recent_doses_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddMostRecentDosesToProfiles < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :most_recent_doses, :hstore 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20160427055217_add_trackable_usages_counts.rb: -------------------------------------------------------------------------------- 1 | class AddTrackableUsagesCounts < ActiveRecord::Migration 2 | def change 3 | add_column :conditions, :trackable_usages_count, :integer, default: 0 4 | add_column :symptoms, :trackable_usages_count, :integer, default: 0 5 | add_column :treatments, :trackable_usages_count, :integer, default: 0 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20160608161002_add_screen_name_to_profile.rb: -------------------------------------------------------------------------------- 1 | class AddScreenNameToProfile < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :screen_name, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20160711182546_add_most_recent_positions_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddMostRecentPositionsToProfiles < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :most_recent_conditions_positions, :hstore 4 | add_column :profiles, :most_recent_symptoms_positions, :hstore 5 | add_column :profiles, :most_recent_treatments_positions, :hstore 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/db/migrate/20161230090023_add_pressure_and_temperature_settings_to_profile.rb: -------------------------------------------------------------------------------- 1 | class AddPressureAndTemperatureSettingsToProfile < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :pressure_units, :integer, default: 0 4 | add_column :profiles, :temperature_units, :integer, default: 0 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20170413144043_add_beta_tester_to_profile.rb: -------------------------------------------------------------------------------- 1 | class AddBetaTesterToProfile < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :beta_tester, :boolean, default: false 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20170504065043_create_crono_jobs.rb: -------------------------------------------------------------------------------- 1 | class CreateCronoJobs < ActiveRecord::Migration 2 | def self.up 3 | create_table :crono_jobs do |t| 4 | t.string :job_id, null: false 5 | t.text :log, limit: 1073741823 # LONGTEXT for MySQL 6 | t.datetime :last_performed_at 7 | t.boolean :healthy 8 | t.timestamps null: false 9 | end 10 | add_index :crono_jobs, [:job_id], unique: true 11 | end 12 | 13 | def self.down 14 | drop_table :crono_jobs 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /backend/db/migrate/20170508151200_add_notify_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddNotifyToProfiles < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :notify, :boolean, default: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20170509114220_add_notify_token_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddNotifyTokenToProfiles < ActiveRecord::Migration 2 | def up 3 | add_column :profiles, :notify_token, :string 4 | Profile.find_each(batch_size: 500) do |profile| 5 | profile.send(:generate_notify_token) 6 | profile.save 7 | end 8 | end 9 | 10 | def down 11 | remove_column :profiles, :notify_token 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/db/migrate/20170612160120_add_slug_name_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddSlugNameToProfiles < ActiveRecord::Migration 2 | def up 3 | add_column :profiles, :slug_name, :string 4 | add_index :profiles, :slug_name 5 | 6 | Profile.find_each(batch_size: 500) do |profile| 7 | profile.send(:ensure_slug_name) 8 | profile.save 9 | end 10 | end 11 | 12 | def down 13 | remove_column :profiles, :slug_name 14 | remove_index :profiles, :slug_name 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /backend/db/migrate/20170717153650_add_notify_top_posts_to_profile.rb: -------------------------------------------------------------------------------- 1 | class AddNotifyTopPostsToProfile < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :notify_top_posts, :boolean, default: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20170731083613_add_global_to_foods_and_tags.rb: -------------------------------------------------------------------------------- 1 | class AddGlobalToFoodsAndTags < ActiveRecord::Migration 2 | def change 3 | add_column :foods, :global, :boolean, default: true 4 | add_column :tags, :global, :boolean, default: true 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/db/migrate/20170731123835_add_trackable_usage_count_to_tags.rb: -------------------------------------------------------------------------------- 1 | class AddTrackableUsageCountToTags < ActiveRecord::Migration 2 | def change 3 | add_column :tags, :trackable_usages_count, :integer, default: 0 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20170731125044_create_user_tags.rb: -------------------------------------------------------------------------------- 1 | class CreateUserTags < ActiveRecord::Migration 2 | def change 3 | create_table :user_tags do |t| 4 | t.belongs_to :user, index: true, foreign_key: true 5 | t.belongs_to :tag, index: true, foreign_key: true 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20170801124153_add_trackable_ability_to_foods.rb: -------------------------------------------------------------------------------- 1 | class AddTrackableAbilityToFoods < ActiveRecord::Migration 2 | def change 3 | add_column :foods, :trackable_usages_count, :integer, default: 0 4 | 5 | create_table :user_foods do |t| 6 | t.belongs_to :user, index: true, foreign_key: true 7 | t.belongs_to :food, index: true, foreign_key: true 8 | 9 | t.timestamps null: false 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/db/migrate/20170817154145_create_positions.rb: -------------------------------------------------------------------------------- 1 | class CreatePositions < ActiveRecord::Migration 2 | def change 3 | create_table :positions do |t| 4 | t.string :postal_code, null: false 5 | t.string :location_name, null: false 6 | t.decimal :latitude, {precision: 10, scale: 7} 7 | t.decimal :longitude, {precision: 10, scale: 7} 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/db/migrate/20170818085110_add_position_reference_to_weather.rb: -------------------------------------------------------------------------------- 1 | class AddPositionReferenceToWeather < ActiveRecord::Migration 2 | def change 3 | add_reference :weathers, :position, foreign_key: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/migrate/20170822122800_add_checkin_reminder_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddCheckinReminderToProfiles < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :checkin_reminder, :boolean, default: false 4 | add_column :profiles, :checkin_reminder_at, :datetime 5 | add_column :profiles, :time_zone_name, :string 6 | add_column :profiles, :reminder_job_id, :string 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/db/migrate/20171011142928_add_rejected_type_to_profiles.rb: -------------------------------------------------------------------------------- 1 | class AddRejectedTypeToProfiles < ActiveRecord::Migration 2 | def change 3 | add_column :profiles, :rejected_type, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /backend/db/seeds.rb: -------------------------------------------------------------------------------- 1 | Rake::Task["usda:load"].invoke 2 | -------------------------------------------------------------------------------- /backend/db/seeds/development/users.seeds.rb: -------------------------------------------------------------------------------- 1 | [ 2 | "test@flaredown.com" 3 | ].each do |email| 4 | FactoryBot.create(:user, email: email) unless User.exists?(email: email) 5 | end 6 | -------------------------------------------------------------------------------- /backend/lib/pusher_client.rb: -------------------------------------------------------------------------------- 1 | class PusherClient 2 | include Singleton 3 | 4 | def initialize 5 | Pusher.app_id = ENV["PUSHER_APP_ID"] 6 | Pusher.key = ENV["PUSHER_KEY"] 7 | Pusher.secret = ENV["PUSHER_SECRET"] 8 | end 9 | 10 | def push(channel, event, message) 11 | Pusher.trigger(channel, event, ActiveSupport::JSON.encode(message)) 12 | end 13 | 14 | def authenticate!(user, socket_id) 15 | Pusher[user.notification_channel].authenticate(socket_id, user_id: user.id) 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /backend/lib/tasks/encrypt_user_id.rake: -------------------------------------------------------------------------------- 1 | namespace :app do 2 | desc "flaredown | encrypt user_id" 3 | task encrypt_user_id: :environment do 4 | puts "Updating #{Checkin.count} checkins:\n" 5 | 6 | Checkin.where(:user_id.exists => true).order_by(date: :desc).each_with_index do |c, i| 7 | c.user_id = c[:user_id] 8 | 9 | c.unset(:user_id) 10 | c.save 11 | 12 | puts i if i % 100 == 0 13 | end 14 | 15 | puts "\nDone." 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /backend/lib/tasks/notifications_scheduler.rake: -------------------------------------------------------------------------------- 1 | namespace :notification do 2 | desc "Schedule NotificationDispatcher" 3 | task dispatcher: :environment do 4 | NotificationDispatcher.perform_async 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/lib/tasks/rubocop.rake: -------------------------------------------------------------------------------- 1 | if Rails.env.development? 2 | require "rubocop/rake_task" 3 | RuboCop::RakeTask.new 4 | end 5 | -------------------------------------------------------------------------------- /backend/lib/tasks/weekly_top_posts_scheduler.rake: -------------------------------------------------------------------------------- 1 | namespace :weekly_top_posts do 2 | desc "Schedule TopPostsMailerDispatcher" 3 | task dispatcher: :environment do 4 | TopPostsMailerDispatcher.perform_async 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/log/.keep -------------------------------------------------------------------------------- /backend/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "lockfileVersion": 1 3 | } 4 | -------------------------------------------------------------------------------- /backend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/public/favicon.ico -------------------------------------------------------------------------------- /backend/public/images/optional_email_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/public/images/optional_email_img.png -------------------------------------------------------------------------------- /backend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /backend/spec/factories/checkin/conditions.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :checkin_condition, class: Checkin::Condition do 3 | transient do 4 | values { [(0..4).to_a + [nil]] } 5 | end 6 | condition_id { FactoryBot.create(:condition).id } 7 | value { values.sample } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/spec/factories/checkin/symptoms.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :checkin_symptom, class: Checkin::Symptom do 3 | transient do 4 | values { [(0..4).to_a + [nil]] } 5 | end 6 | symptom_id { FactoryBot.create(:symptom).id } 7 | value { values.sample } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/spec/factories/checkin/treatments.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :checkin_treatment, class: Checkin::Treatment do 3 | transient do 4 | values { ["20 mg", "2 ml", "3 x 1 cap", "2 x 10 mg", nil, "3 x 4 ml", "1 cap", "5 ml", "2 x 2 cap"] } 5 | end 6 | treatment_id { FactoryBot.create(:treatment).id } 7 | value { values.sample } 8 | is_taken { value.present? ? true : [true, false].sample } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /backend/spec/factories/checkins.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :checkin do 3 | user_id { FactoryBot.create(:user).id } 4 | sequence(:date) { |n| Time.zone.now - n.days } 5 | note { FFaker::Lorem.sentence } 6 | tag_ids { FactoryBot.create_list(:tag, 2).map(&:id) } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/factories/comments.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :comment do 3 | body { "This is a comment." } 4 | encrypted_user_id { create(:user).encrypted_id } 5 | post_id { create(:post).id } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/factories/foods.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :food do 3 | sequence(:ndb_no) { |n| "id#{n}" } 4 | 5 | comname { FFaker::Lorem.sentence } 6 | long_desc { FFaker::Lorem.sentence } 7 | sciname { FFaker::Lorem.sentence } 8 | shrt_desc { FFaker::Lorem.sentence } 9 | 10 | trait :personal do 11 | global { false } 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/spec/factories/notifications.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :notification do 3 | kind { "reaction" } 4 | notificateable { create(:post) } 5 | 6 | encrypted_user_id { create(:user).encrypted_id } 7 | encrypted_notify_user_id { create(:user).encrypted_id } 8 | 9 | initialize_with { new(attributes) } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/factories/patterns.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :pattern do 3 | encrypted_user_id { create(:user).encrypted_id } 4 | start_at { Time.zone.now } 5 | end_at { 2.days.from_now } 6 | name { "Chuck Norris" } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/factories/posts.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :post do 3 | title { "Frustrating day" } 4 | body { "Today was really hard with my symptoms" } 5 | encrypted_user_id { "abcd1234" } 6 | symptom_ids { [create(:symptom).id] } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/factories/promotion_rate.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :promotion_rate do 3 | user_id { FactoryBot.create(:user).id } 4 | sequence(:date) { |n| Time.zone.now - n.days } 5 | score { rand(1..10) } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/factories/reactions.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :reaction do 3 | value { ":smile:" } 4 | encrypted_user_id { create(:user).encrypted_id } 5 | reactable { create(:post) } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/factories/tags.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: tags 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # 9 | 10 | FactoryBot.define do 11 | factory :tag do 12 | sequence(:name) { |n| "Tag#{n}" } 13 | 14 | trait :personal do 15 | global { false } 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /backend/spec/factories/topic_followings.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :topic_following do 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /backend/spec/factories/user_conditions.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: user_conditions 4 | # 5 | # id :integer not null, primary key 6 | # user_id :integer 7 | # condition_id :integer 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | FactoryBot.define do 13 | factory :user_condition do 14 | user 15 | association :condition, :personal 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /backend/spec/factories/user_foods.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :user_food do 3 | user 4 | association :food, :personal 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/spec/factories/user_symptoms.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: user_symptoms 4 | # 5 | # id :integer not null, primary key 6 | # user_id :integer 7 | # symptom_id :integer 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | FactoryBot.define do 13 | factory :user_symptom do 14 | user 15 | association :symptom, :personal 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /backend/spec/factories/user_tags.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :user_tag do 3 | user 4 | association :tag, :personal 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/spec/factories/user_treatments.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: user_treatments 4 | # 5 | # id :integer not null, primary key 6 | # user_id :integer 7 | # treatment_id :integer 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | FactoryBot.define do 13 | factory :user_treatment do 14 | user 15 | association :treatment, :personal 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /backend/spec/factories/weathers.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :weather do 3 | date { "MyString" } 4 | postal_code { "MyString" } 5 | icon { "MyString" } 6 | temperature_min { 1.5 } 7 | temperature_max { 1.5 } 8 | precip_intensity { 1.5 } 9 | pressure { 1.5 } 10 | humidity { 1.5 } 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /backend/spec/fixtures/usda/FOOD_DES.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/spec/fixtures/usda/FOOD_DES.txt -------------------------------------------------------------------------------- /backend/spec/mailers/previews/checkin_reminder_mailer_preview.rb: -------------------------------------------------------------------------------- 1 | class CheckinReminderMailerPreview < ActionMailer::Preview 2 | # Preview emails at http://localhost:3000/rails/mailers/checkin_reminder_mailer/remind 3 | def remind 4 | CheckinReminderMailer.remind(email: "test@flaredown.com") 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /backend/spec/mailers/previews/top_posts_mailer_preview.rb: -------------------------------------------------------------------------------- 1 | class TopPostsMailerPreview < ActionMailer::Preview 2 | # Preview emails at http://localhost:3000/rails/mailers/top_posts_mailer/notify 3 | def notify 4 | TopPostsMailer.notify(email: "test@flaredown.com", top_posts_ids: top_posts_ids) 5 | end 6 | 7 | def top_posts_ids 8 | posts = Post.pluck(:id).map(&:to_s) 9 | posts.any? ? posts.first(5) : [] 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/mailers/previews/user_data_mailer_preview.rb: -------------------------------------------------------------------------------- 1 | # Preview all emails at http://localhost:3000/rails/mailers/user_data_mailer 2 | class UserDataMailerPreview < ActionMailer::Preview 3 | # Preview this email at http://localhost:3000/rails/mailers/user_data_mailer/trackings_csv 4 | def trackings_csv 5 | UserDataMailer.trackings_csv("some@email.yo", "header1,header2\nvalue1, value2\n") 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/models/checkin/condition_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe Checkin::Condition, type: :model do 4 | include Mongoid::Matchers 5 | 6 | it_behaves_like "fiveable" 7 | 8 | describe "Relations" do 9 | it { is_expected.to belong_to(:checkin) } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/models/checkin/symptom_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe Checkin::Symptom, type: :model do 4 | include Mongoid::Matchers 5 | 6 | it_behaves_like "fiveable" 7 | 8 | describe "Relations" do 9 | it { is_expected.to belong_to(:checkin) } 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /backend/spec/models/checkin/treatment_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | RSpec.describe Checkin::Treatment, type: :model do 4 | include Mongoid::Matchers 5 | 6 | describe "Relations" do 7 | it { is_expected.to belong_to(:checkin) } 8 | end 9 | 10 | describe "Respond to" do 11 | it { is_expected.to respond_to(:value) } 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /backend/spec/models/comment_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe Comment do 4 | describe "Validations" do 5 | it { is_expected.to validate_presence_of(:body) } 6 | it { is_expected.to validate_presence_of(:encrypted_user_id) } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/models/position_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe Position do 4 | describe "Validations" do 5 | it { is_expected.to validate_presence_of(:postal_code) } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/models/post_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe Post do 4 | describe "Validations" do 5 | it { is_expected.to validate_presence_of(:body) } 6 | it { is_expected.to validate_presence_of(:title) } 7 | it { is_expected.to validate_presence_of(:encrypted_user_id) } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /backend/spec/models/promotion_rate_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe PromotionRate do 4 | include Mongoid::Matchers 5 | 6 | describe "Relations" do 7 | it { is_expected.to belong_to(:checkin) } 8 | end 9 | 10 | describe "Validations" do 11 | it { is_expected.to validate_presence_of(:checkin) } 12 | it { is_expected.to validate_uniqueness_of(:checkin_id) } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /backend/spec/models/tag_spec.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: tags 4 | # 5 | # id :integer not null, primary key 6 | # created_at :datetime not null 7 | # updated_at :datetime not null 8 | # 9 | 10 | require "rails_helper" 11 | 12 | RSpec.describe Tag, type: :model do 13 | describe "Respond to" do 14 | it { is_expected.to respond_to(:name) } 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /backend/spec/models/topic_following_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe TopicFollowing do 4 | describe "Validations" do 5 | it { is_expected.to validate_presence_of(:encrypted_user_id) } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/models/weather_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe Weather do 4 | describe "Validations" do 5 | it { is_expected.to validate_uniqueness_of(:date).scoped_to(:position_id) } 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/support/activesupport_timehelpers.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include ActiveSupport::Testing::TimeHelpers 3 | end 4 | -------------------------------------------------------------------------------- /backend/spec/support/devise.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.before(:each, type: :controller) do 3 | @request.env["devise.mapping"] = Devise.mappings[:user] 4 | end 5 | 6 | config.include Devise::Test::ControllerHelpers, type: :controller 7 | end 8 | -------------------------------------------------------------------------------- /backend/spec/support/factory_bot.rb: -------------------------------------------------------------------------------- 1 | RSpec.configure do |config| 2 | config.include FactoryBot::Syntax::Methods 3 | end 4 | -------------------------------------------------------------------------------- /backend/spec/support/foreign_key_checks.rb: -------------------------------------------------------------------------------- 1 | module ForeignKeyChecks 2 | extend ActiveSupport::Concern 3 | 4 | def disable_foreign_key_checks(table) 5 | ActiveRecord::Base.connection.execute("ALTER TABLE #{table} DISABLE TRIGGER ALL;") 6 | end 7 | 8 | def enable_foreign_key_checks(table) 9 | ActiveRecord::Base.connection.execute("ALTER TABLE #{table} ENABLE TRIGGER ALL;") 10 | end 11 | end 12 | 13 | RSpec.configure do |config| 14 | config.include ForeignKeyChecks, type: :model 15 | end 16 | -------------------------------------------------------------------------------- /backend/spec/support/response.rb: -------------------------------------------------------------------------------- 1 | module ResponseHelpers 2 | extend ActiveSupport::Concern 3 | 4 | def response_body 5 | @response_body ||= ActiveSupport::HashWithIndifferentAccess.new( 6 | (begin 7 | JSON.parse(response.body, symbolize_names: true) 8 | rescue 9 | {} 10 | end) 11 | ) 12 | end 13 | end 14 | 15 | RSpec.configure do |config| 16 | config.include ResponseHelpers, type: :controller 17 | end 18 | -------------------------------------------------------------------------------- /backend/spec/support/shared_examples/fiveable.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | shared_examples_for "fiveable" do 4 | include Mongoid::Matchers 5 | 6 | it { is_expected.to respond_to(:value) } 7 | it { is_expected.to validate_inclusion_of(:value).to_allow(0..4) } 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/system/signup_spec.rb: -------------------------------------------------------------------------------- 1 | require "system_spec_helper" 2 | 3 | RSpec.describe "signup flow" do 4 | it "loads the root page" do 5 | visit "/" 6 | expect(page.title).to eq "Flaredown" 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /backend/spec/system/support/cuprite_config.rb: -------------------------------------------------------------------------------- 1 | require "capybara/cuprite" 2 | 3 | Capybara.register_driver(:cuprite) do |app| 4 | Capybara::Cuprite::Driver.new( 5 | app, 6 | window_size: [1200, 800], 7 | browser_options: {}, 8 | process_timeout: 10, 9 | inspector: true, 10 | headless: ENV["HEADLESS_CHROME"] != "false" 11 | ) 12 | end 13 | 14 | Capybara.default_driver = Capybara.javascript_driver = :cuprite 15 | -------------------------------------------------------------------------------- /backend/tmp/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/backend/tmp/.keep -------------------------------------------------------------------------------- /frontend/.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components", 3 | "analytics": false 4 | } 5 | -------------------------------------------------------------------------------- /frontend/.dockerignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | dist 4 | tmp 5 | .git 6 | README.md 7 | LICENSE 8 | .gitignore 9 | -------------------------------------------------------------------------------- /frontend/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | end_of_line = lf 10 | charset = utf-8 11 | trim_trailing_whitespace = true 12 | insert_final_newline = true 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.hbs] 17 | insert_final_newline = false 18 | 19 | [*.{diff,md}] 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /frontend/.ember-cli: -------------------------------------------------------------------------------- 1 | { 2 | /** 3 | Ember CLI sends analytics information by default. The data is completely 4 | anonymous, but there are times when you might want to disable this behavior. 5 | 6 | Setting `disableAnalytics` to true will prevent any data from being sent. 7 | */ 8 | "disableAnalytics": false 9 | } 10 | -------------------------------------------------------------------------------- /frontend/.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | # compiled output 4 | /dist 5 | /tmp 6 | 7 | # dependencies 8 | /node_modules 9 | /bower_components 10 | 11 | # misc 12 | /.sass-cache 13 | /connect.lock 14 | /coverage/* 15 | /libpeerconnection.log 16 | npm-debug.log 17 | testem.log 18 | -------------------------------------------------------------------------------- /frontend/.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /frontend/.nvmrc: -------------------------------------------------------------------------------- 1 | v14.21.3 2 | -------------------------------------------------------------------------------- /frontend/.watchmanconfig: -------------------------------------------------------------------------------- 1 | { 2 | "ignore_dirs": ["tmp", "dist"] 3 | } 4 | -------------------------------------------------------------------------------- /frontend/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM --platform=linux/amd64 node:14.21 2 | 3 | # Force npm version 7 4 | RUN npm i -g npm@7 5 | 6 | WORKDIR /app 7 | 8 | COPY package*.json bower.json .bowerrc .npmrc ./ 9 | 10 | RUN npm install 11 | 12 | # May no be needed in future version of node 13 | ENV OPENSSL_CONF=/dev/null 14 | 15 | COPY . . 16 | 17 | CMD ["npm", "start"] 18 | -------------------------------------------------------------------------------- /frontend/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /frontend/app/authenticators/devise.js: -------------------------------------------------------------------------------- 1 | import Devise from 'ember-simple-auth/authenticators/devise'; 2 | import ENV from 'flaredown/config/environment'; 3 | 4 | 5 | export default Devise.extend({ 6 | serverTokenEndpoint: `${ENV.apiHost}/api/sessions`, 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/authorizers/devise.js: -------------------------------------------------------------------------------- 1 | import Devise from 'ember-simple-auth/authorizers/devise'; 2 | 3 | export default Devise.extend(); 4 | -------------------------------------------------------------------------------- /frontend/app/components/additional-info.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | classNames: ['flex-container flaredown-additional-info'], 5 | tagName: ['div'], 6 | }); 7 | -------------------------------------------------------------------------------- /frontend/app/components/checkin/summary-posts.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | get, 5 | computed, 6 | inject: { 7 | service, 8 | }, 9 | Component, 10 | } = Ember; 11 | 12 | export default Component.extend({ 13 | store: service(), 14 | session: service(), 15 | classNames: ['summary-posts'], 16 | 17 | model: computed(function(){ 18 | return get(this, 'store').query('post', { summary: true }); 19 | }), 20 | }); 21 | -------------------------------------------------------------------------------- /frontend/app/components/checkin/summary-step.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | model: Ember.computed.alias('parentView.model'), 6 | checkin: Ember.computed.alias('model.checkin'), 7 | 8 | actions: { 9 | completeStep() { 10 | this.get('onStepCompleted')(); 11 | }, 12 | goBack() { 13 | this.get('onGoBack')(); 14 | } 15 | } 16 | 17 | }); 18 | -------------------------------------------------------------------------------- /frontend/app/components/draggable-item.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | classNames: ['draggable-item'], 5 | 6 | classNameBindings: ['dragging:activated'], 7 | dragging: false, 8 | 9 | attributeBindings: ['draggable'], 10 | draggable: 'true', 11 | 12 | dragStart(event) { 13 | this.set('dragging', true); 14 | return event.dataTransfer.setData('text/plain', this.get('itemId')); 15 | }, 16 | dragEnd() { 17 | this.set('dragging', false); 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /frontend/app/components/form-for.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | tagName: 'form', 5 | classNames: 'form', 6 | 7 | submit: function() { 8 | this.sendAction('onSubmit', this.get('for')); 9 | return false; 10 | } 11 | 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/app/components/invitation-form.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | classNames: ['invitation-form'], 5 | 6 | actions: { 7 | acceptInvitation() { 8 | var model = this.get('model'); 9 | model.set('passwordConfirmation', model.get('password')); 10 | model.save().then( () => { 11 | this.get('session').authenticate('authenticator:devise', model.get('email'), model.get('password') ); 12 | }); 13 | } 14 | } 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/app/components/join-footer.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | get, 5 | inject: { 6 | service, 7 | }, 8 | Component, 9 | } = Ember; 10 | 11 | export default Component.extend({ 12 | tagName: ['div'], 13 | classNames: ['flex-container', 'footer', 'join-footer'], 14 | 15 | _routing: service('-routing'), 16 | 17 | click() { 18 | get(this, '_routing').transitionTo('signup'); 19 | }, 20 | }); 21 | -------------------------------------------------------------------------------- /frontend/app/components/label-switch.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | tagName: 'label', 5 | classNames: ['label-switch'] 6 | }); 7 | -------------------------------------------------------------------------------- /frontend/app/components/multi-group.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | classNames: ['tags-group'], 5 | 6 | objects: Ember.computed('scope', function() { 7 | return this.store.query(this.get('modelName'), { scope: this.get('scope') }); 8 | }), 9 | 10 | actions: { 11 | clickObj(obj) { 12 | this.get('onItemClicked')(obj); 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /frontend/app/components/nav/discussions-unread.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Component, 5 | inject: { 6 | service, 7 | }, 8 | computed: { 9 | alias, 10 | }, 11 | } = Ember; 12 | 13 | export default Component.extend({ 14 | tagName: '', 15 | 16 | notifications: service(), 17 | 18 | postId: alias('notifications.first.postId'), 19 | }); 20 | -------------------------------------------------------------------------------- /frontend/app/components/navigation-bar.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import CheckinByDate from 'flaredown/mixins/checkin-by-date'; 3 | 4 | export default Ember.Component.extend(CheckinByDate, { 5 | classNames: 'navigation-bar', 6 | }); 7 | -------------------------------------------------------------------------------- /frontend/app/components/onboarding/completed-step.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import CheckinByDate from 'flaredown/mixins/checkin-by-date'; 3 | import moment from 'moment'; 4 | 5 | export default Ember.Component.extend(CheckinByDate, { 6 | 7 | model: Ember.computed.alias('parentView.model'), 8 | 9 | actions: { 10 | completeStep() { 11 | this.routeToCheckinsForDate(moment(new Date()).format("YYYY-MM-DD")); 12 | }, 13 | 14 | goBack() { 15 | this.get('onGoBack')(); 16 | } 17 | } 18 | 19 | }); 20 | -------------------------------------------------------------------------------- /frontend/app/components/onboarding/conditions-step.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | model: Ember.computed.alias('parentView.model'), 6 | 7 | actions: { 8 | completeStep() { 9 | this.get('onStepCompleted')(); 10 | }, 11 | goBack() { 12 | this.get('onGoBack')(); 13 | } 14 | } 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/app/components/onboarding/personal-step.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | model: Ember.computed.alias('parentView.model'), 6 | 7 | actions: { 8 | completeStep() { 9 | var profile = this.get('model.profile'); 10 | profile.save().then( () => { 11 | this.get('onStepCompleted')(); 12 | }); 13 | } 14 | } 15 | 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/app/components/onboarding/symptoms-step.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | model: Ember.computed.alias('parentView.model'), 6 | 7 | actions: { 8 | completeStep() { 9 | this.get('onStepCompleted')(); 10 | }, 11 | 12 | goBack() { 13 | this.get('onGoBack')(); 14 | } 15 | } 16 | 17 | }); 18 | -------------------------------------------------------------------------------- /frontend/app/components/onboarding/treatments-step.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | model: Ember.computed.alias('parentView.model'), 6 | 7 | actions: { 8 | completeStep() { 9 | this.get('onStepCompleted')(); 10 | }, 11 | 12 | goBack() { 13 | this.get('onGoBack')(); 14 | } 15 | } 16 | 17 | }); 18 | -------------------------------------------------------------------------------- /frontend/app/components/password/expired-token.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import { translationMacro as t } from "ember-i18n"; 3 | 4 | const { 5 | inject: { service }, 6 | Component, 7 | } = Ember; 8 | 9 | export default Component.extend({ 10 | i18n: service(), 11 | 12 | tagName: 'div', 13 | classNames: ['expired-box'], 14 | 15 | textBeforeLink: t("password.update.textBeforeLink"), 16 | textAfterLink: t("password.update.textAfterLink"), 17 | }); 18 | -------------------------------------------------------------------------------- /frontend/app/components/pattern/initial-step.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import { translationMacro as t } from "ember-i18n"; 3 | 4 | const { 5 | inject: { service }, 6 | Component 7 | } = Ember; 8 | 9 | export default Component.extend({ 10 | i18n: service(), 11 | 12 | classNames: ['flaredown-transparent-box'], 13 | buttonLabel: t("history.step.initial.buttonText"), 14 | }); 15 | -------------------------------------------------------------------------------- /frontend/app/components/posts/post-topics.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Component, 5 | } = Ember; 6 | 7 | export default Component.extend({ 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/components/posts/profile-picture.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UserNameable from 'flaredown/mixins/user-nameable'; 3 | 4 | const { 5 | computed: { 6 | alias 7 | }, 8 | Component, 9 | } = Ember; 10 | 11 | export default Component.extend(UserNameable, { 12 | classNames: ['profile-circle'], 13 | pictureLetter: alias('session.actualUser.profile.screenName.0'), 14 | }); 15 | -------------------------------------------------------------------------------- /frontend/app/components/power-select/dropdown-name-desc.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | classNames: ['power-select-dropdown-name-desc'] 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/components/power-select/dropdown-trackable-create.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | classNames: ['power-select-dropdown-trackable', 'create'] 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/components/power-select/dropdown-trackable.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | classNames: ['power-select-dropdown-trackable', 'option'] 6 | 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/components/power-select/selected-name.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Component.extend({ 4 | 5 | tagName: 'span', 6 | classNames: ['ember-power-select-selected-item'] 7 | 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/components/share-socials.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | computed, 5 | Component, 6 | } = Ember; 7 | 8 | export default Component.extend({ 9 | classNames: ['shareSocials'], 10 | divideTitles: false, 11 | 12 | baseUrl: computed(function() { 13 | let location = window.location; 14 | 15 | return location.protocol + "//" + location.host; 16 | }), 17 | }); 18 | -------------------------------------------------------------------------------- /frontend/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/app/controllers/.gitkeep -------------------------------------------------------------------------------- /frontend/app/controllers/oracle/index.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Controller, 5 | } = Ember; 6 | 7 | export default Controller.extend({ 8 | actions: { 9 | transitionToResult(oracleRequest) { 10 | this.transitionToRoute('oracle.result', oracleRequest); 11 | }, 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/helpers/capitalize.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export function capitalize(params/*, hash*/) { 4 | if(params[0]) { 5 | return Ember.String.capitalize(params[0]); 6 | } else { 7 | return ''; 8 | } 9 | } 10 | 11 | export default Ember.Helper.helper(capitalize); 12 | -------------------------------------------------------------------------------- /frontend/app/helpers/checkToday.js: -------------------------------------------------------------------------------- 1 | import { helper } from '@ember/component/helper'; 2 | import moment from 'moment'; 3 | 4 | export function checkToday(params) { 5 | let [date, displayText] = params; 6 | const checkdate = moment(new Date()).format("YYYY-MM-DD") == date ? displayText : null 7 | return checkdate 8 | } 9 | 10 | export default helper(checkToday); 11 | -------------------------------------------------------------------------------- /frontend/app/helpers/includes.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export function includes(params) { 4 | return params.slice(1).find(i => i === params[0]); 5 | } 6 | 7 | export default Ember.Helper.helper(includes); 8 | -------------------------------------------------------------------------------- /frontend/app/helpers/indexPlusOne.js: -------------------------------------------------------------------------------- 1 | import { helper } from "@ember/component/helper"; 2 | 3 | export function indexPlusOne(a) { 4 | return parseInt(a) + 1; 5 | } 6 | 7 | export default helper(indexPlusOne); 8 | -------------------------------------------------------------------------------- /frontend/app/helpers/pluralize.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { String: { pluralize } } = Ember; 4 | 5 | export function pluralizeWord(params, options) { 6 | let [count, word] = params; 7 | const { omitCount } = options; 8 | 9 | if (count !== 1) { 10 | count = count || 0; 11 | word = pluralize(word); 12 | } 13 | 14 | return (omitCount ? '' : count + ' ') + word; 15 | } 16 | 17 | export default Ember.Helper.helper(pluralizeWord); 18 | -------------------------------------------------------------------------------- /frontend/app/helpers/truncate-text.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export function truncateText(params, hash) { 4 | const text = params[0]; 5 | const len = hash.limit; 6 | 7 | if (typeof text !== 'undefined') { 8 | if (len !== null && text.length > len) { 9 | return `${text.substr(0, len)}...`; 10 | } else { 11 | return text; 12 | } 13 | } 14 | return ''; 15 | } 16 | 17 | export default Ember.Helper.helper(truncateText); 18 | -------------------------------------------------------------------------------- /frontend/app/instance-initializers/emojis.js: -------------------------------------------------------------------------------- 1 | export function initialize(appInstance) { 2 | appInstance.inject('component:emoji-menu', 'emojis', 'service:emojis'); 3 | appInstance.inject('component:emoji-reaction', 'emojis', 'service:emojis'); 4 | } 5 | 6 | export default { 7 | name: 'emojis', 8 | initialize 9 | }; 10 | -------------------------------------------------------------------------------- /frontend/app/instance-initializers/i18n.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'i18n', 3 | 4 | initialize(application) { 5 | let i18n = application.lookup('service:i18n'); 6 | const lang = typeof navigator !== 'undefined' && (navigator.language || navigator.userLanguage) || 'en'; 7 | 8 | i18n.set('locale', i18n.get('locales').includes(lang) ? lang : 'en'); 9 | 10 | application.inject('service:steps', 'i18n', 'service:i18n'); 11 | }, 12 | }; 13 | -------------------------------------------------------------------------------- /frontend/app/instance-initializers/inject-router-into-components.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'injectRouterIntoComponents', 3 | 4 | initialize: function initialize(application) { 5 | application.inject('component', 'router', 'router:main'); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /frontend/app/instance-initializers/inject-session.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'injectSession', 3 | 4 | initialize: function initialize(application) { 5 | application.inject('controller', 'session', 'service:session'); 6 | application.inject('component', 'session', 'service:session'); 7 | } 8 | }; 9 | -------------------------------------------------------------------------------- /frontend/app/instance-initializers/inject-store-into-components.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'injectStoreIntoComponents', 3 | 4 | initialize: function initialize(application) { 5 | application.inject('component', 'store', 'service:store'); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /frontend/app/instance-initializers/selectable-data.js: -------------------------------------------------------------------------------- 1 | export default { 2 | name: 'selectableData', 3 | 4 | initialize: function initialize(application) { 5 | application.inject('controller:posts/new', 'selectableData', 'service:selectable-data'); 6 | } 7 | }; 8 | -------------------------------------------------------------------------------- /frontend/app/mixins/back-navigateable.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | get, 5 | Mixin, 6 | inject: { 7 | service, 8 | }, 9 | } = Ember; 10 | 11 | export default Mixin.create({ 12 | routeHistory: service(), 13 | 14 | actions: { 15 | navigateBack() { 16 | const previous = get(this, 'routeHistory').popEntry(); 17 | 18 | if (previous) { 19 | this.transitionToRoute(...previous); 20 | } 21 | }, 22 | }, 23 | }); 24 | -------------------------------------------------------------------------------- /frontend/app/mixins/fields-by-units.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Mixin.create({ 4 | pressureFieldByUnits(unit) { 5 | return unit === 'in' ? 'pressureInches' : 'pressure'; 6 | }, 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/mixins/nested-destroyable.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Ember from 'ember'; 3 | 4 | export default Ember.Mixin.create({ 5 | 6 | _destroy: DS.attr('string'), 7 | prepareForDestroy: function() { 8 | this.set('_destroy', '1'); 9 | }, 10 | isPreparedForDestroy: Ember.computed.equal('_destroy', '1') 11 | 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/app/mixins/searchable.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Mixin.create({ 4 | 5 | }); 6 | -------------------------------------------------------------------------------- /frontend/app/mixins/toggle-header-logo.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | set, 5 | inject: { 6 | service, 7 | }, 8 | Mixin, 9 | } = Ember; 10 | 11 | export default Mixin.create({ 12 | logoVisiability: service(), 13 | 14 | activate() { 15 | set(this, 'logoVisiability.showHeaderLogo', false); 16 | }, 17 | 18 | deactivate() { 19 | set(this, 'logoVisiability.showHeaderLogo', true); 20 | }, 21 | }); 22 | -------------------------------------------------------------------------------- /frontend/app/mixins/typeable.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Mixin, 5 | computed, 6 | } = Ember; 7 | 8 | export default Mixin.create({ 9 | modelType: computed(function() { 10 | return this.constructor.modelName; 11 | }), 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/app/mixins/user-nameable.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | computed: { 5 | alias 6 | }, 7 | inject: { 8 | service 9 | }, 10 | Mixin, 11 | } = Ember; 12 | 13 | export default Mixin.create({ 14 | session: service('session'), 15 | dataStore: service('store'), 16 | 17 | screenName: alias('session.actualUser.profile.screenName'), 18 | }); 19 | -------------------------------------------------------------------------------- /frontend/app/models/chart-list.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { 4 | attr, 5 | Model, 6 | } = DS; 7 | 8 | export default Model.extend({ 9 | payload: attr(), 10 | }); 11 | -------------------------------------------------------------------------------- /frontend/app/models/chart.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | startAt: DS.attr(), 5 | endAt: DS.attr(), 6 | 7 | //Associations 8 | checkins: DS.hasMany('checkin', { async: false } ), 9 | trackables: DS.hasMany('trackable', { async: false, polymorphic: true, inverse: null } ), 10 | 11 | cachedCheckins: DS.hasMany('checkin', { async: false } ) 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/models/checkin-trackable.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Colorable from 'flaredown/mixins/colorable'; 3 | import NestedDestroyable from 'flaredown/mixins/nested-destroyable'; 4 | 5 | export default DS.Model.extend(Colorable, NestedDestroyable, { 6 | 7 | position: DS.attr('number'), 8 | checkin: DS.belongsTo('checkin'), 9 | 10 | }); 11 | -------------------------------------------------------------------------------- /frontend/app/models/condition.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Trackable from 'flaredown/models/trackable'; 3 | 4 | export default Trackable.extend({ 5 | 6 | //Attributes 7 | name: DS.attr('string') 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/models/country.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | //Attributes 5 | name: DS.attr('string') 6 | }); 7 | -------------------------------------------------------------------------------- /frontend/app/models/day-habit.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import RankedEnum from 'flaredown/models/ranked-enum'; 3 | 4 | export default RankedEnum.extend({ 5 | 6 | description: DS.attr('string') 7 | 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/models/dose.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Searchable from 'flaredown/mixins/searchable'; 3 | 4 | export default DS.Model.extend(Searchable, { 5 | 6 | //Attributes 7 | name: DS.attr('string') 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/models/education-level.js: -------------------------------------------------------------------------------- 1 | import RankedEnum from 'flaredown/models/ranked-enum'; 2 | 3 | export default RankedEnum.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /frontend/app/models/ethnicity.js: -------------------------------------------------------------------------------- 1 | import RankedEnum from 'flaredown/models/ranked-enum'; 2 | 3 | export default RankedEnum.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /frontend/app/models/food.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Colorable from 'flaredown/mixins/colorable'; 3 | 4 | export default DS.Model.extend(Colorable, { 5 | name: DS.attr('string'), 6 | 7 | colorId: '35', 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/models/invitation.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | user: DS.belongsTo('user', { async: false }), 5 | email: DS.attr('string'), 6 | password: DS.attr('string'), 7 | passwordConfirmation: DS.attr('string') 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/models/notification.js: -------------------------------------------------------------------------------- 1 | import attr from 'ember-data/attr'; 2 | import Model from 'ember-data/model'; 3 | 4 | export default Model.extend({ 5 | kind: attr('string'), 6 | count: attr('number'), 7 | postId: attr('string'), 8 | postTitle: attr('string'), 9 | unread: attr('boolean'), 10 | notificateableId: attr('string'), 11 | notificateableType: attr('string'), 12 | notifier_username: attr('string'), 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/models/password.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | email: DS.attr('string'), 5 | resetPasswordToken: DS.attr('string'), 6 | password: DS.attr('string'), 7 | passwordConfirmation: DS.attr('string'), 8 | currentPassword: DS.attr('string') 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/models/pattern.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Ember from 'ember'; 3 | 4 | const { 5 | A, 6 | } = Ember; 7 | 8 | export default DS.Model.extend({ 9 | name: DS.attr('string'), 10 | startAt: DS.attr('string'), 11 | endAt: DS.attr('string'), 12 | authorName: DS.attr('string'), 13 | includes: DS.attr('raw', { 14 | defaultValue() { return A([]); } 15 | }), 16 | }); 17 | -------------------------------------------------------------------------------- /frontend/app/models/postable.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { 4 | Model, 5 | hasMany, 6 | } = DS; 7 | 8 | export default Model.extend({ 9 | posts: hasMany('post', { async: false }), 10 | comments: hasMany('comment', { async: false }), 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/app/models/promotion-rate.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { 4 | attr, 5 | Model, 6 | belongsTo, 7 | } = DS; 8 | 9 | export default Model.extend({ 10 | score: attr('number'), 11 | feedback: attr('string'), 12 | checkin: belongsTo('checkin'), 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/models/ranked-enum.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | 5 | name: DS.attr('string'), 6 | rank: DS.attr('number') 7 | 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/models/reactable.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { 4 | Model, 5 | hasMany, 6 | } = DS; 7 | 8 | export default Model.extend({ 9 | reactions: hasMany('reaction', { async: false }), 10 | }); 11 | -------------------------------------------------------------------------------- /frontend/app/models/reaction.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | const { 4 | attr, 5 | Model, 6 | } = DS; 7 | 8 | export default Model.extend({ 9 | count: attr('number'), 10 | value: attr('string'), 11 | participated: attr('boolean'), 12 | reactable_id: attr('string'), 13 | reactable_type: attr('string'), 14 | }); 15 | -------------------------------------------------------------------------------- /frontend/app/models/search.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | searchables: DS.hasMany('searchable', { async: false, polymorphic: true, inverse: null } ), 5 | }); 6 | -------------------------------------------------------------------------------- /frontend/app/models/session.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | baseUrl: DS.attr("string"), 5 | notificationChannel: DS.attr("string"), 6 | facebookAppId: DS.attr("string"), 7 | discourseEnabled: DS.attr("string"), 8 | discourseUrl: DS.attr("string"), 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/models/sex.js: -------------------------------------------------------------------------------- 1 | import RankedEnum from 'flaredown/models/ranked-enum'; 2 | 3 | export default RankedEnum.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /frontend/app/models/symptom.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Trackable from 'flaredown/models/trackable'; 3 | 4 | export default Trackable.extend({ 5 | 6 | //Attributes 7 | name: DS.attr('string') 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/models/tag.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Typeable from 'flaredown/mixins/typeable'; 3 | import Colorable from 'flaredown/mixins/colorable'; 4 | import Searchable from 'flaredown/mixins/searchable'; 5 | 6 | export default DS.Model.extend(Typeable, Colorable, Searchable, { 7 | name: DS.attr('string'), 8 | usersCount: DS.attr('number'), 9 | colorId: '35', 10 | }); 11 | -------------------------------------------------------------------------------- /frontend/app/models/topic-following.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Ember from 'ember'; 3 | import Topicable from 'flaredown/mixins/topicable'; 4 | 5 | const { 6 | attr, 7 | Model, 8 | } = DS; 9 | 10 | const { 11 | computed: { 12 | alias, 13 | }, 14 | } = Ember; 15 | 16 | export default Model.extend(Topicable, { 17 | updatedAt: attr('date'), 18 | 19 | topicsCount: alias('topics.length'), 20 | }); 21 | -------------------------------------------------------------------------------- /frontend/app/models/trackable.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Typeable from 'flaredown/mixins/typeable'; 3 | import Colorable from 'flaredown/mixins/colorable'; 4 | import Searchable from 'flaredown/mixins/searchable'; 5 | 6 | export default DS.Model.extend(Typeable, Colorable, Searchable, { 7 | usersCount: DS.attr('number'), 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/models/tracking.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | 5 | // Attributes 6 | startAt: DS.attr('date'), 7 | endAt: DS.attr('date'), 8 | trackableType: DS.attr('string'), 9 | colorId: DS.attr('string'), 10 | 11 | // Associations 12 | user: DS.belongsTo('user'), 13 | trackable: DS.belongsTo('trackable', { polymorphic: true }), 14 | 15 | }); 16 | -------------------------------------------------------------------------------- /frontend/app/models/treatment.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import Trackable from 'flaredown/models/trackable'; 3 | 4 | export default Trackable.extend({ 5 | 6 | //Attributes 7 | name: DS.attr('string') 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/models/user.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Model.extend({ 4 | //Attributes 5 | email: DS.attr('string'), 6 | createdAt: DS.attr('date'), 7 | 8 | //Associations 9 | profile: DS.belongsTo('profile'), 10 | topicFollowing: DS.belongsTo('topic-following'), 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /frontend/app/routes/chart.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import AuthenticatedRouteMixin from 'flaredown/mixins/authenticated-route-mixin'; 3 | 4 | const { 5 | Route, 6 | } = Ember; 7 | 8 | export default Route.extend(AuthenticatedRouteMixin, { 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/routes/delete.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import AuthenticatedRouteMixin from 'flaredown/mixins/authenticated-route-mixin'; 3 | 4 | const { 5 | Route, 6 | } = Ember; 7 | 8 | export default Route.extend(AuthenticatedRouteMixin, { 9 | model() { 10 | return this.get('session.currentUser'); 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/app/routes/invitation.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UnauthenticatedRouteMixin from 'flaredown/mixins/unauthenticated-route-mixin'; 3 | 4 | export default Ember.Route.extend(UnauthenticatedRouteMixin, { 5 | 6 | }); 7 | -------------------------------------------------------------------------------- /frontend/app/routes/login.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UnauthenticatedRouteMixin from 'flaredown/mixins/unauthenticated-route-mixin'; 3 | 4 | const { 5 | Route, 6 | } = Ember; 7 | 8 | export default Route.extend(UnauthenticatedRouteMixin, { 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/routes/notifications.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import HistoryTrackable from 'flaredown/mixins/history-trackable'; 3 | 4 | const { 5 | get, 6 | inject: { 7 | service, 8 | }, 9 | Route 10 | } = Ember; 11 | 12 | export default Route.extend(HistoryTrackable, { 13 | notifications: service('notifications'), 14 | 15 | model() { 16 | return get(this, 'notifications'); 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /frontend/app/routes/oracle.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Route, 5 | } = Ember; 6 | 7 | export default Route.extend({ 8 | }); 9 | -------------------------------------------------------------------------------- /frontend/app/routes/oracle/index.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Route, 5 | } = Ember; 6 | 7 | export default Route.extend({ 8 | model() { 9 | return this.store.createRecord('oracleRequest', { symptomIds: [] }); 10 | }, 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/app/routes/oracle/result.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Route, 5 | } = Ember; 6 | 7 | export default Route.extend({ 8 | model(params) { 9 | return this.store.findRecord('oracleRequest', params.id); 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/app/routes/password.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UnauthenticatedRouteMixin from 'flaredown/mixins/unauthenticated-route-mixin'; 3 | 4 | export default Ember.Route.extend(UnauthenticatedRouteMixin, {}); 5 | -------------------------------------------------------------------------------- /frontend/app/routes/password/update.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UnauthenticatedRouteMixin from 'flaredown/mixins/unauthenticated-route-mixin'; 3 | 4 | const { 5 | get, 6 | Route, 7 | } = Ember; 8 | 9 | export default Route.extend(UnauthenticatedRouteMixin, { 10 | model(params) { 11 | if (typeof FastBoot === 'undefined') { 12 | return get(this, 'store').findRecord('password', params.password_id).catch(() => null); 13 | } 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /frontend/app/routes/patterns/index.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import AuthenticatedRouteMixin from 'flaredown/mixins/authenticated-route-mixin'; 3 | 4 | const { 5 | get, 6 | Route, 7 | } = Ember; 8 | 9 | export default Route.extend(AuthenticatedRouteMixin, { 10 | model() { 11 | return get(this, 'store').findAll('pattern'); 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/routes/posts.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Route.extend({ 4 | }); 5 | -------------------------------------------------------------------------------- /frontend/app/routes/posts/followings.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import HistoryTrackable from 'flaredown/mixins/history-trackable'; 3 | import AuthenticatedRouteMixin from 'flaredown/mixins/authenticated-route-mixin'; 4 | 5 | const { 6 | get, 7 | Route, 8 | } = Ember; 9 | 10 | export default Route.extend(HistoryTrackable, AuthenticatedRouteMixin, { 11 | model() { 12 | return get(this, 'session.currentUser').then(user => get(user, 'topicFollowing')); 13 | }, 14 | }); 15 | -------------------------------------------------------------------------------- /frontend/app/routes/posts/profile.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import PostableGetable from 'flaredown/mixins/postable-getable'; 3 | import HistoryTrackable from 'flaredown/mixins/history-trackable'; 4 | 5 | const { 6 | Route, 7 | } = Ember; 8 | 9 | export default Route.extend(PostableGetable, HistoryTrackable, { 10 | model() { 11 | return this.getPostables(1); 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/routes/settings.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import AuthenticatedRouteMixin from 'flaredown/mixins/authenticated-route-mixin'; 3 | 4 | const { 5 | Route, 6 | get 7 | } = Ember; 8 | 9 | export default Route.extend(AuthenticatedRouteMixin, { 10 | model() { 11 | return get(this, 'session.currentUser').then(user => user.get('profile')); 12 | }, 13 | 14 | actions: { 15 | invalidateSession() { 16 | this.get('session').invalidate(); 17 | }, 18 | }, 19 | }); 20 | -------------------------------------------------------------------------------- /frontend/app/routes/signup.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UnauthenticatedRouteMixin from 'flaredown/mixins/unauthenticated-route-mixin'; 3 | 4 | const { 5 | Route, 6 | } = Ember; 7 | 8 | export default Route.extend(UnauthenticatedRouteMixin, { 9 | 10 | model() { 11 | return this.store.createRecord('registration'); 12 | }, 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/routes/unsubscribe.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | get, 5 | Route, 6 | inject : { service } 7 | } = Ember; 8 | 9 | export default Route.extend({ 10 | ajax: service('ajax'), 11 | 12 | beforeModel(transition) { 13 | const notifyToken = transition.params.unsubscribe.notify_token; 14 | 15 | get(this, 'ajax').request(`/unsubscribe/${ notifyToken }`, { 16 | type: 'GET', 17 | data: transition.queryParams, 18 | }); 19 | } 20 | }); 21 | -------------------------------------------------------------------------------- /frontend/app/serializers/chart.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import { ActiveModelSerializer } from 'active-model-adapter'; 3 | 4 | export default ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, { 5 | attrs: { 6 | trackables: { embedded: 'always' } 7 | }, 8 | 9 | normalize(modelClass, resourceHash, prop) { 10 | return this._super(modelClass, resourceHash, prop); 11 | }, 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /frontend/app/serializers/checkin-treatment.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import { ActiveModelSerializer } from 'active-model-adapter'; 3 | 4 | export default ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, { 5 | attrs: { 6 | dose: { embedded: 'always' } 7 | } 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/serializers/comment.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import { ActiveModelSerializer } from 'active-model-adapter'; 3 | 4 | const { 5 | EmbeddedRecordsMixin, 6 | } = DS; 7 | 8 | export default ActiveModelSerializer.extend(EmbeddedRecordsMixin, { 9 | attrs: { 10 | reactions: { embedded: 'always' }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/app/serializers/post.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import { ActiveModelSerializer } from 'active-model-adapter'; 3 | 4 | const { 5 | EmbeddedRecordsMixin, 6 | } = DS; 7 | 8 | export default ActiveModelSerializer.extend(EmbeddedRecordsMixin, { 9 | attrs: { 10 | reactions: { embedded: 'always' }, 11 | }, 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/app/serializers/search.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | import { ActiveModelSerializer } from 'active-model-adapter'; 3 | 4 | export default ActiveModelSerializer.extend(DS.EmbeddedRecordsMixin, { 5 | attrs: { 6 | searchables: { embedded: 'always' } 7 | } 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /frontend/app/services/chart-journal-switcher.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { Service } = Ember; 4 | 5 | export default Service.extend({ 6 | journalIsVisible: false, 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/services/chart-selected-dates.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { Service } = Ember; 4 | 5 | export default Service.extend({}); 6 | -------------------------------------------------------------------------------- /frontend/app/services/logo-visiability.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { 4 | Service, 5 | } = Ember; 6 | 7 | export default Service.extend({ 8 | showHeaderLogo: true, 9 | showHeaderPAth: true, 10 | }); 11 | -------------------------------------------------------------------------------- /frontend/app/services/patterns-loading.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | const { Service } = Ember; 4 | 5 | export default Service.extend({ 6 | loadingPatterns: false, 7 | }); 8 | -------------------------------------------------------------------------------- /frontend/app/services/pusher/subscription.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | 3 | export default Ember.Object.extend({ 4 | channelName: '', 5 | 6 | initSubscription: Ember.on('init', function() { 7 | this.get('connection.client').subscribe(this.get('channelName')) .bind_all(this.handlerEvents.bind(this)); 8 | }), 9 | 10 | handlerEvents: function(eventName, data) { 11 | if(Ember.isPresent(eventName)) { 12 | Ember.tryInvoke(this, eventName, [data]); 13 | } 14 | } 15 | }); 16 | -------------------------------------------------------------------------------- /frontend/app/session-stores/application.js: -------------------------------------------------------------------------------- 1 | import CookieStore from 'ember-simple-auth/session-stores/cookie'; 2 | 3 | export default CookieStore.extend({ 4 | cookieExpirationTime: 2147483647, 5 | }); 6 | -------------------------------------------------------------------------------- /frontend/app/styles/_badges.scss: -------------------------------------------------------------------------------- 1 | $badges: ( 2 | "default": $progress-gray, 3 | "primary": $primary, 4 | ); 5 | 6 | @each $badge-type, $color in $badges { 7 | .badge-#{$badge-type} { 8 | background-color: $color; 9 | border-radius: $base-font-size * 5; 10 | color: darken($color, 40%); 11 | display: inline-block; 12 | font-size: $base-font-size; 13 | line-height: 1; 14 | padding: 0.4em 1.2em; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/styles/_progressbar.scss: -------------------------------------------------------------------------------- 1 | .progress-container { 2 | width: 100%; 3 | height: 1.5em; 4 | position: relative; 5 | font-size: 6px; 6 | background-color: $progress-gray; 7 | } 8 | 9 | .progressbar { 10 | height: 100%; 11 | position: absolute; 12 | line-height: inherit; 13 | background-color: $progress-blue; 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/styles/_userengage.scss: -------------------------------------------------------------------------------- 1 | .civ-chat-window { 2 | .ca__chat-expand-button { 3 | bottom: 115px; 4 | } 5 | 6 | .ca__chat-launcher-body { 7 | bottom: 175px; 8 | } 9 | 10 | @include media ($medium-screen) { 11 | .ca__chat-expand-button { 12 | bottom: 60px; 13 | } 14 | 15 | .ca__chat-launcher-body { 16 | bottom: 120px; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend/app/styles/bitters/_base.scss: -------------------------------------------------------------------------------- 1 | // Bitters 1.2.0 2 | // http://bitters.bourbon.io 3 | // Copyright 2013-2015 thoughtbot, inc. 4 | // MIT License 5 | 6 | @import "variables"; 7 | 8 | // Neat Settings -- uncomment if using Neat -- must be imported before Neat 9 | @import "grid-settings"; 10 | 11 | @import "buttons"; 12 | @import "forms"; 13 | @import "lists"; 14 | @import "offsets"; 15 | @import "tables"; 16 | @import "typography"; 17 | 18 | -------------------------------------------------------------------------------- /frontend/app/styles/bitters/_grid-settings.scss: -------------------------------------------------------------------------------- 1 | // Neat Overrides 2 | // $column: 90px; 3 | // $gutter: 30px; 4 | // $grid-columns: 12; 5 | // $max-width: 1200px; 6 | 7 | // Neat Breakpoints 8 | $medium-screen: 600px; 9 | $large-screen: 900px; 10 | -------------------------------------------------------------------------------- /frontend/app/styles/bitters/_lists.scss: -------------------------------------------------------------------------------- 1 | ul, 2 | ol { 3 | list-style-type: none; 4 | margin: 0; 5 | padding: 0; 6 | } 7 | 8 | dl { 9 | margin-bottom: $small-spacing; 10 | 11 | dt { 12 | font-weight: 600; 13 | margin-top: $small-spacing; 14 | } 15 | 16 | dd { 17 | margin: 0; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /frontend/app/styles/bitters/_offsets.scss: -------------------------------------------------------------------------------- 1 | .vert-offset-top-1 { 2 | margin-top: 1em; 3 | } 4 | 5 | .vert-offset-top-2 { 6 | margin-top: 2em; 7 | } 8 | 9 | .vert-offset-top-3-conditional { 10 | @media screen and (max-width: $medium-screen) { 11 | margin-top: 3em; 12 | } 13 | } 14 | 15 | .vert-offset-bottom-0_5 { 16 | margin-bottom: .5em; 17 | } 18 | 19 | .vert-offset-bottom-1 { 20 | margin-bottom: 1em; 21 | } 22 | 23 | .vert-offset-bottom-2 { 24 | margin-bottom: 2em; 25 | } 26 | -------------------------------------------------------------------------------- /frontend/app/styles/bitters/_tables.scss: -------------------------------------------------------------------------------- 1 | table { 2 | border-collapse: collapse; 3 | margin: $small-spacing 0; 4 | table-layout: fixed; 5 | width: 100%; 6 | } 7 | 8 | th { 9 | border-bottom: 1px solid shade($base-border-color, 25%); 10 | font-weight: 600; 11 | padding: $small-spacing 0; 12 | text-align: left; 13 | } 14 | 15 | td { 16 | border-bottom: $base-border; 17 | padding: $small-spacing 0; 18 | } 19 | 20 | tr, 21 | td, 22 | th { 23 | vertical-align: middle; 24 | } 25 | -------------------------------------------------------------------------------- /frontend/app/styles/components/add-trackings.scss: -------------------------------------------------------------------------------- 1 | h6.trackable { 2 | font-size: 1.2em; 3 | &:before { 4 | content: "✔ "; 5 | color: $primary; 6 | } 7 | } 8 | .explainer { 9 | font-size: 0.8em; 10 | font-style: italic; 11 | margin: .5em; 12 | color: $grey; 13 | text-align: left; 14 | } 15 | -------------------------------------------------------------------------------- /frontend/app/styles/components/checkin/summary-step.scss: -------------------------------------------------------------------------------- 1 | .checkin-summary { 2 | @include outer-container; 3 | max-width: 500px; 4 | .summary-title { 5 | color: $primary; 6 | text-align: center; 7 | -webkit-margin-after: 0em; 8 | } 9 | .note-textarea { 10 | height: 130px; 11 | } 12 | } 13 | 14 | .summary-posts { 15 | padding-top: 5%; 16 | } 17 | -------------------------------------------------------------------------------- /frontend/app/styles/components/checkin/weather-step.scss: -------------------------------------------------------------------------------- 1 | .measurements { 2 | display: flex; 3 | } 4 | 5 | .measurement { 6 | flex-grow: 1; 7 | 8 | &.clickable { 9 | text-decoration: underline; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /frontend/app/styles/components/form-field.scss: -------------------------------------------------------------------------------- 1 | .form-field { 2 | .error-message { 3 | font-size: 0.9em; 4 | font-weight: bold; 5 | margin-top: -8px; 6 | } 7 | } -------------------------------------------------------------------------------- /frontend/app/styles/components/invitation-form.scss: -------------------------------------------------------------------------------- 1 | .invitation-form { 2 | @include outer-container; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/app/styles/components/login-form.scss: -------------------------------------------------------------------------------- 1 | .login-form { 2 | @include outer-container; 3 | @include single-col; 4 | } 5 | -------------------------------------------------------------------------------- /frontend/app/styles/components/reset-password-form.scss: -------------------------------------------------------------------------------- 1 | .reset-password-form { 2 | @include outer-container; 3 | @include single-col; 4 | h4 { 5 | font-size: 1.5em; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /frontend/app/styles/components/save-status.scss: -------------------------------------------------------------------------------- 1 | .save-status { 2 | color: $grey; 3 | // padding: 20px 0 20px 0; 4 | text-align: center; 5 | } 6 | -------------------------------------------------------------------------------- /frontend/app/styles/components/signup-form.scss: -------------------------------------------------------------------------------- 1 | .signup-form { 2 | @include outer-container; 3 | @include single-col; 4 | 5 | .g-recaptcha { 6 | margin-bottom: 0.75em; 7 | } 8 | 9 | .checkbox { 10 | flex-direction: row; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /frontend/app/styles/components/tags-group.scss: -------------------------------------------------------------------------------- 1 | .tags-group { 2 | margin-top: 10px; 3 | text-align: center; 4 | li { 5 | display: inline-block; 6 | font-size: 1.2em; 7 | margin: 0 10px; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /frontend/app/styles/components/update-password-form.scss: -------------------------------------------------------------------------------- 1 | .update-password-form { 2 | @include outer-container; 3 | } 4 | 5 | .expired-box { 6 | padding: 1.2em; 7 | text-align: center; 8 | } 9 | -------------------------------------------------------------------------------- /frontend/app/styles/spinner.scss: -------------------------------------------------------------------------------- 1 | :root { 2 | --sk-color: #{$primary}; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/app/templates/application-loading.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | -------------------------------------------------------------------------------- /frontend/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 | {{partial "application/header"}} 2 | 3 | {{outlet}} 4 | 5 | {{partial "application/footer"}} 6 | 7 | {{#if session.isAuthenticated}} 8 | {{bottom-nav}} 9 | {{/if}} 10 | 11 | {{outlet "modal"}} 12 | -------------------------------------------------------------------------------- /frontend/app/templates/application/footer.hbs: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /frontend/app/templates/application/header.hbs: -------------------------------------------------------------------------------- 1 | {{#unless (includes currentPath 'oracle' 'oracle.index' 'oracle.result')}} 2 | 9 | {{/unless}} 10 | 11 | -------------------------------------------------------------------------------- /frontend/app/templates/application/three-bounce-spinner.hbs: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 | -------------------------------------------------------------------------------- /frontend/app/templates/chart.hbs: -------------------------------------------------------------------------------- 1 | {{health-dashboard}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/checkin/show.hbs: -------------------------------------------------------------------------------- 1 | {{checkin-dialog model=model}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/additional-info.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{inline-svg 'circle' class='icon'}} 3 | Design your health profile 4 |
5 | 6 |
7 | {{inline-svg 'circle' class='icon'}} 8 | Track symptoms and treatments 9 |
10 | 11 |
12 | {{inline-svg 'circle' class='icon'}} 13 | Share you story 14 |
15 | -------------------------------------------------------------------------------- /frontend/app/templates/components/at-js-autocomplete.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/chart/g-blank-flat.hbs: -------------------------------------------------------------------------------- 1 | {{model.name}} 2 | HIDE 3 | 4 | 5 | 6 | 12 | -------------------------------------------------------------------------------- /frontend/app/templates/components/chart/g-blank-trackable.hbs: -------------------------------------------------------------------------------- 1 | {{model.name}} 2 | HIDE 3 | 4 | 5 | 6 | {{chart/g-ruler yScale=yScale yRulers=yRulers width=width}} 7 | -------------------------------------------------------------------------------- /frontend/app/templates/components/chart/g-ruler.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{#each rulers as |ruler|}} 3 | {{ruler.label}} 4 | {{/each}} 5 | 6 | 7 | 8 | {{#each rulers as |ruler|}} 9 | 15 | {{/each}} 16 | 17 | -------------------------------------------------------------------------------- /frontend/app/templates/components/chart/g-timeline.hbs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/checkin-navigation.hbs: -------------------------------------------------------------------------------- 1 | {{#each steps as |step|}} 2 | {{link-to step.shortTitle 'checkin.show' checkinId step.stepName}} 3 | {{/each}} 4 | -------------------------------------------------------------------------------- /frontend/app/templates/components/checkin/-step-header.hbs: -------------------------------------------------------------------------------- 1 | {{save-status record=checkin}} 2 | 3 |

{{step.title}}

4 | 5 | {{#if step.hint}} 6 |
{{{step.hint}}}
7 | {{/if}} 8 | -------------------------------------------------------------------------------- /frontend/app/templates/components/checkin/note-edit.hbs: -------------------------------------------------------------------------------- 1 |

Journal

2 | {{textarea value=(mut checkin.note) 3 | placeholder="Leave a note about your day" 4 | class="note-textarea fs-private" }} 5 | -------------------------------------------------------------------------------- /frontend/app/templates/components/checkin/summary-posts.hbs: -------------------------------------------------------------------------------- 1 |

Your daily digest

2 | 3 | {{#if model.isPending}} 4 | {{partial "application/three-bounce-spinner"}} 5 | {{else}} 6 | {{#each model as |post|}} 7 | {{posts/topic-post post=post isAuthenticatedUser= session.isAuthenticated}} 8 | {{/each}} 9 | {{/if}} 10 | -------------------------------------------------------------------------------- /frontend/app/templates/components/checkin/summary-step.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 | {{checkin/note-edit checkin=checkin}} 4 | 5 |
6 | {{checkin/weather-step}} 7 |
8 | 9 | {{checkin/summary-posts}} 10 | 11 | {{step-controls step=step 12 | showBack=false 13 | forwardLabel=(inline-svg 'history_white') 14 | onForward=(action "completeStep") }} 15 | -------------------------------------------------------------------------------- /frontend/app/templates/components/data-export-initiator.hbs: -------------------------------------------------------------------------------- 1 | {{#if exportIsScheduled}} 2 | You will get an email with your data soon 3 | {{else}} 4 | Download my data 5 | {{/if}} 6 | -------------------------------------------------------------------------------- /frontend/app/templates/components/draggable-dropzone.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/draggable-item.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/emoji-reaction.hbs: -------------------------------------------------------------------------------- 1 |
2 |
{{reaction.count}}
3 | -------------------------------------------------------------------------------- /frontend/app/templates/components/emoji-reactions.hbs: -------------------------------------------------------------------------------- 1 | {{#each reactable.reactions as |reaction|}} 2 | {{emoji-reaction reaction=reaction onParticipate=(action "onEmojiSelect")}} 3 | {{/each}} 4 | 5 | {{#if isAuthenticatedUser}} 6 | {{#emoji-menu onSelect=(action "onEmojiSelect")}}Add reaction{{/emoji-menu}} 7 | {{/if}} 8 | -------------------------------------------------------------------------------- /frontend/app/templates/components/form-field.hbs: -------------------------------------------------------------------------------- 1 | 4 | 5 | {{yield this}} 6 | 7 | {{#if hasError}} 8 |

9 | {{errors}} 10 |

11 | {{/if}} 12 | -------------------------------------------------------------------------------- /frontend/app/templates/components/form-for.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/invitation-form.hbs: -------------------------------------------------------------------------------- 1 | {{#form-for for=model onSubmit="acceptInvitation"}} 2 | 3 | {{#form-field for="email" label="Email"}} 4 | {{input value=model.email placeholder="Email"}} 5 | {{/form-field}} 6 | 7 | {{#form-field for="password" label="Password"}} 8 | {{input type="password" value=model.password placeholder="Password"}} 9 | {{/form-field}} 10 | 11 | {{input type="submit" value="Unlock early access"}} 12 | {{/form-for}} 13 | -------------------------------------------------------------------------------- /frontend/app/templates/components/join-footer.hbs: -------------------------------------------------------------------------------- 1 | Join Flaredown 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/journal-entry.hbs: -------------------------------------------------------------------------------- 1 |
{{date}}
2 | 3 |

{{checkin.note}}

4 | 5 |

{{pip-label symptomCeil}} symptoms

6 | 7 |
8 |
9 |
10 | 11 | {{link-to 'Edit' 'checkin.show' checkinId 'summary'}} 12 | -------------------------------------------------------------------------------- /frontend/app/templates/components/journal-list.hbs: -------------------------------------------------------------------------------- 1 | {{#each checkins as |checkin|}} 2 | {{journal-entry checkin=checkin}} 3 | {{/each}} 4 | 5 | {{#if noCheckinsPresent}} 6 |
No journal entries yet
7 | {{/if}} 8 | 9 | {{ember-ic-you triggerDistance=40}} 10 | 11 | {{#if loadingCheckins}} 12 | {{partial "application/three-bounce-spinner"}} 13 | {{/if}} 14 | -------------------------------------------------------------------------------- /frontend/app/templates/components/label-switch.hbs: -------------------------------------------------------------------------------- 1 | {{input type="checkbox" checked=checked}} 2 |
3 | -------------------------------------------------------------------------------- /frontend/app/templates/components/multi-group.hbs: -------------------------------------------------------------------------------- 1 | {{#if objects}} 2 |

{{title}}

3 | 8 | {{/if}} 9 | -------------------------------------------------------------------------------- /frontend/app/templates/components/onboarding/completed-step.hbs: -------------------------------------------------------------------------------- 1 | 2 | 3 | {{step-controls step=step 4 | forwardLabel="Checkin" 5 | onBackward=(action "goBack") 6 | onForward=(action "completeStep") }} 7 | -------------------------------------------------------------------------------- /frontend/app/templates/components/onboarding/conditions-step.hbs: -------------------------------------------------------------------------------- 1 | {{add-trackings trackableType="condition"}} 2 | {{step-controls step=step 3 | onBackward=(action "goBack") 4 | onForward=(action "completeStep") }} 5 | -------------------------------------------------------------------------------- /frontend/app/templates/components/onboarding/personal-step.hbs: -------------------------------------------------------------------------------- 1 | {{profile-form model=model.profile forOnboarding=true }} 2 | {{step-controls step=step 3 | onForward=(action 'completeStep') }} 4 | -------------------------------------------------------------------------------- /frontend/app/templates/components/onboarding/reminder-step.hbs: -------------------------------------------------------------------------------- 1 | {{add-reminder model=model.profile}} 2 | {{step-controls step=step 3 | onBackward=(action "goBack") 4 | onForward=(action "completeStep") }} 5 | -------------------------------------------------------------------------------- /frontend/app/templates/components/onboarding/symptoms-step.hbs: -------------------------------------------------------------------------------- 1 | {{add-trackings trackableType="symptom"}} 2 | {{step-controls step=step 3 | onBackward=(action "goBack") 4 | onForward=(action "completeStep") }} 5 | -------------------------------------------------------------------------------- /frontend/app/templates/components/onboarding/treatments-step.hbs: -------------------------------------------------------------------------------- 1 | {{add-trackings trackableType="treatment"}} 2 | {{step-controls step=step 3 | onBackward=(action "goBack") 4 | onForward=(action "completeStep") }} 5 | -------------------------------------------------------------------------------- /frontend/app/templates/components/password/expired-token.hbs: -------------------------------------------------------------------------------- 1 | {{textBeforeLink}} 2 | {{link-to 'here' 'password.reset'}} 3 | {{textAfterLink}} 4 | -------------------------------------------------------------------------------- /frontend/app/templates/components/pattern/chart-hover.hbs: -------------------------------------------------------------------------------- 1 |
2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/pattern/chart-legend-item.hbs: -------------------------------------------------------------------------------- 1 | {{item.label}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/pattern/initial-step.hbs: -------------------------------------------------------------------------------- 1 |

{{t "history.step.initial.title"}}

2 | 3 |

{{t "history.step.initial.text"}}

4 | 5 |
6 | 9 |
10 | -------------------------------------------------------------------------------- /frontend/app/templates/components/pattern/svg-initial.hbs: -------------------------------------------------------------------------------- 1 | {{#pattern/chart-group data=data startAt=startAt endAt=endAt svgInitial=true as |chart|}} 2 | {{#each chart.data.series as |item index|}} 3 | {{pattern/chart-item data=item index=index chart=chart initialSvg=true }} 4 | {{/each}} 5 | {{/pattern/chart-group}} 6 | 7 | -------------------------------------------------------------------------------- /frontend/app/templates/components/pip-tag.hbs: -------------------------------------------------------------------------------- 1 |
2 |

{{pip-label value}}

3 |
4 | -------------------------------------------------------------------------------- /frontend/app/templates/components/posts/activity-notification.hbs: -------------------------------------------------------------------------------- 1 | {{#link-to 'posts.show' notification.postId (query-params anchor=notificationAnchor) class="colorable-clr-39"}} 2 | {{fullResponse}} 3 | {{/link-to}} 4 | -------------------------------------------------------------------------------- /frontend/app/templates/components/posts/post-comment.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 |

{{comment.userName}}

4 |

{{comment.bodyWithBr}}

5 | 6 | {{emoji-reactions reactable=comment isAuthenticatedUser=isAuthenticatedUser}} 7 | -------------------------------------------------------------------------------- /frontend/app/templates/components/posts/post-topics.hbs: -------------------------------------------------------------------------------- 1 | {{#each post.topics as |topic|}} 2 | {{#link-to 'posts.topic' topic.modelType topic.id}} 3 | {{topic.name}} 4 | {{/link-to}} 5 | {{/each}} 6 | -------------------------------------------------------------------------------- /frontend/app/templates/components/posts/profile-picture.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{pictureLetter}} 3 |
4 | -------------------------------------------------------------------------------- /frontend/app/templates/components/posts/topic-comment.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{#link-to 'posts.show' comment.post.id (query-params anchor=(concat 'anchor-' comment.id)) class="colorable-clr-39"}} 3 | Responded to {{comment.post.title}} 4 | {{/link-to}} 5 |
6 | 7 |

{{#link-to 'posts.show' comment.post.id class="colorable-clr-39"}}{{comment.body}}{{/link-to}}

8 | 9 | {{emoji-reactions reactable=comment}} 10 | -------------------------------------------------------------------------------- /frontend/app/templates/components/power-select/dropdown-name-desc.hbs: -------------------------------------------------------------------------------- 1 |
{{option.name}}
2 |
{{option.description}}
3 | -------------------------------------------------------------------------------- /frontend/app/templates/components/power-select/dropdown-trackable-create.hbs: -------------------------------------------------------------------------------- 1 |
“{{typedText}}”
2 |
Add new {{trackableType}}
3 | -------------------------------------------------------------------------------- /frontend/app/templates/components/power-select/dropdown-trackable.hbs: -------------------------------------------------------------------------------- 1 |
{{trackable.name}}
2 |
{{trackable.usersCount}} users
3 | -------------------------------------------------------------------------------- /frontend/app/templates/components/power-select/selected-name.hbs: -------------------------------------------------------------------------------- 1 | {{option.name}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/reset-password-form.hbs: -------------------------------------------------------------------------------- 1 |

{{resetPassMessage}}

2 | 3 | {{#form-for onSubmit="resetPassword"}} 4 |
5 | 6 | {{input value=model.email placeholder='name@domain.com' class='form-control'}} 7 |
8 | 9 | {{#link-to 'login'}}Back to Login{{/link-to}} 10 | {{input type="submit" class="btn btn-primary right" value="Reset your password"}} 11 | {{/form-for}} 12 | -------------------------------------------------------------------------------- /frontend/app/templates/components/save-status.hbs: -------------------------------------------------------------------------------- 1 | {{#if record.isSaving}} 2 | Saving changes... 3 | {{else if record.hasDirtyAttributes}} 4 | {{#if saveFailed}} 5 | {{{saveFailureMessage}}} 6 | {{else}} 7 | You have unsaved changes, please wait 8 | {{/if}} 9 | {{else}} 10 | All changes saved 11 | {{/if}} 12 | -------------------------------------------------------------------------------- /frontend/app/templates/components/scroll-to-anchor.hbs: -------------------------------------------------------------------------------- 1 | {{yield}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/share-socials.hbs: -------------------------------------------------------------------------------- 1 | {{#if divideTitles}} 2 | {{#fb-share-btn url=baseUrl}}Share{{/fb-share-btn}} 3 | {{#twitter-share-btn url=baseUrl title=title.tw}}Tweet{{/twitter-share-btn}} 4 | {{else}} 5 | {{#fb-share-btn url=post.show title=title text=text}}Share{{/fb-share-btn}} 6 | {{#twitter-share-btn url=post.show title=title text=text}}Tweet{{/twitter-share-btn}} 7 | {{/if}} 8 | -------------------------------------------------------------------------------- /frontend/app/templates/components/toggle-logo.hbs: -------------------------------------------------------------------------------- 1 | {{#if showHeaderLogo}} 2 | 3 | 4 | {{#if showHeaderPath}} 5 | {{#if (eq currentPathTitle 'signup')}} 6 |

Create your Flaredown account

7 | {{else}} 8 |

{{capitalize currentPathTitle}}

9 | {{/if}} 10 | {{/if}} 11 | {{/if}} 12 | -------------------------------------------------------------------------------- /frontend/app/templates/components/tumblr-share.hbs: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /frontend/app/templates/components/twitter-share-btn.hbs: -------------------------------------------------------------------------------- 1 | 2 | {{yield}} 3 | -------------------------------------------------------------------------------- /frontend/app/templates/components/view-remove-tracking.hbs: -------------------------------------------------------------------------------- 1 | {{#unless tracking.isDeleted}} 2 |
3 | {{tracking.trackable.name}} 4 | × 5 |
6 | {{/unless}} 7 | -------------------------------------------------------------------------------- /frontend/app/templates/invitation.hbs: -------------------------------------------------------------------------------- 1 | {{invitation-form model=model}} 2 | 3 | -------------------------------------------------------------------------------- /frontend/app/templates/login.hbs: -------------------------------------------------------------------------------- 1 | {{login-form}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/notifications.hbs: -------------------------------------------------------------------------------- 1 |
2 | {{ navigation-links title=title optionObjects=foundTopics onSearch=(action "searchObjects") onGo=(action "goToTopic") isAuthenticatedUser=session.isAuthenticated}} 3 | 4 | {{#each model.unread as |notification|}} 5 | {{posts/activity-notification notification=notification}} 6 | {{/each}} 7 | 8 | {{#each model.read as |notification|}} 9 | {{posts/activity-notification notification=notification}} 10 | {{/each}} 11 | -------------------------------------------------------------------------------- /frontend/app/templates/onboarding.hbs: -------------------------------------------------------------------------------- 1 | {{onboarding-dialog model=model}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/oracle.hbs: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |

Chornic Illness Oracle

5 |

{{link-to "by Flaredown" "application"}}

6 |
7 | 8 | {{outlet}} 9 | -------------------------------------------------------------------------------- /frontend/app/templates/oracle/index.hbs: -------------------------------------------------------------------------------- 1 | {{oracle/request-form model=model transitionToResult=(action 'transitionToResult')}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/oracle/result.hbs: -------------------------------------------------------------------------------- 1 | {{oracle/result-summary model=model}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/password/reset.hbs: -------------------------------------------------------------------------------- 1 | {{reset-password-form}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/password/update.hbs: -------------------------------------------------------------------------------- 1 | {{#if model}} 2 | {{update-password-form model=model onPasswordUpdated="routeToLogin"}} 3 | {{else}} 4 | {{password/expired-token}} 5 | {{/if}} 6 | -------------------------------------------------------------------------------- /frontend/app/templates/patterns/index.hbs: -------------------------------------------------------------------------------- 1 | {{shared-patterns/dialog patterns=model}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/patterns/shared.hbs: -------------------------------------------------------------------------------- 1 |

2 | 3 | {{pattern/index-step 4 | patterns=model 5 | authorPage=false 6 | }} 7 | -------------------------------------------------------------------------------- /frontend/app/templates/posts.hbs: -------------------------------------------------------------------------------- 1 | {{outlet}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/signup.hbs: -------------------------------------------------------------------------------- 1 | {{signup-form model=model isError=true}} 2 | -------------------------------------------------------------------------------- /frontend/app/templates/unsubscribe.hbs: -------------------------------------------------------------------------------- 1 |

You've unsubscribed successfully

2 | -------------------------------------------------------------------------------- /frontend/app/transforms/raw.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Transform.extend({ 4 | deserialize(serialized) { 5 | return serialized; 6 | }, 7 | 8 | serialize(deserialized) { 9 | return deserialized; 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/app/transforms/time-zone-name.js: -------------------------------------------------------------------------------- 1 | import DS from 'ember-data'; 2 | 3 | export default DS.Transform.extend({ 4 | deserialize(serialized) { 5 | return serialized.split('_').join(' '); 6 | }, 7 | 8 | serialize(deserialized) { 9 | return deserialized.split(' ').join('_'); 10 | } 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/app/utils/i18n/missing-message.js: -------------------------------------------------------------------------------- 1 | export default function() { 2 | return ''; 3 | } 4 | -------------------------------------------------------------------------------- /frontend/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "flaredown", 3 | "dependencies": { 4 | "pace": "vectart/pace", 5 | "pickadate": "^3.5.6", 6 | "At.js": "^1.5.4" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /frontend/config/targets.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | browsers: [ 3 | 'ie 9', 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions' 7 | ] 8 | }; 9 | -------------------------------------------------------------------------------- /frontend/lib/full-story/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "full-story", 3 | "keywords": [ 4 | "ember-addon" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /frontend/lib/heap-analytics/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "heap-analytics", 3 | "keywords": [ 4 | "ember-addon" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /frontend/public/assets/crystal-ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/crystal-ball.png -------------------------------------------------------------------------------- /frontend/public/assets/emoji/IconsetSmiles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/emoji/IconsetSmiles.png -------------------------------------------------------------------------------- /frontend/public/assets/emoji/emoji_spritesheet_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/emoji/emoji_spritesheet_0.png -------------------------------------------------------------------------------- /frontend/public/assets/emoji/emoji_spritesheet_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/emoji/emoji_spritesheet_1.png -------------------------------------------------------------------------------- /frontend/public/assets/emoji/emoji_spritesheet_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/emoji/emoji_spritesheet_2.png -------------------------------------------------------------------------------- /frontend/public/assets/emoji/emoji_spritesheet_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/emoji/emoji_spritesheet_3.png -------------------------------------------------------------------------------- /frontend/public/assets/emoji/emoji_spritesheet_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/emoji/emoji_spritesheet_4.png -------------------------------------------------------------------------------- /frontend/public/assets/fonts/proximanova-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/fonts/proximanova-regular-webfont.eot -------------------------------------------------------------------------------- /frontend/public/assets/fonts/proximanova-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/fonts/proximanova-regular-webfont.ttf -------------------------------------------------------------------------------- /frontend/public/assets/fonts/proximanova-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/fonts/proximanova-regular-webfont.woff -------------------------------------------------------------------------------- /frontend/public/assets/fonts/proximanovacond-regular-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/fonts/proximanovacond-regular-webfont.eot -------------------------------------------------------------------------------- /frontend/public/assets/fonts/proximanovacond-regular-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/fonts/proximanovacond-regular-webfont.ttf -------------------------------------------------------------------------------- /frontend/public/assets/fonts/proximanovacond-regular-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/fonts/proximanovacond-regular-webfont.woff -------------------------------------------------------------------------------- /frontend/public/assets/nav_icons/arrow-left.svg: -------------------------------------------------------------------------------- 1 | arrow-left_1 -------------------------------------------------------------------------------- /frontend/public/assets/nav_icons/arrow-right.svg: -------------------------------------------------------------------------------- 1 | arrow-right_1 -------------------------------------------------------------------------------- /frontend/public/assets/nav_icons/circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /frontend/public/assets/nav_icons/explore.svg: -------------------------------------------------------------------------------- 1 | explore_1 -------------------------------------------------------------------------------- /frontend/public/assets/nav_icons/eye.svg: -------------------------------------------------------------------------------- 1 | eye icon_1 -------------------------------------------------------------------------------- /frontend/public/assets/onboarding-success-sm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/onboarding-success-sm.png -------------------------------------------------------------------------------- /frontend/public/assets/onboarding_success.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/onboarding_success.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/clear-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/clear-day.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/clear-night.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/clear-night.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/cloudy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/cloudy.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/default.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/fog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/fog.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/partly-cloudy-day.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/partly-cloudy-day.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/partly-cloudy-night.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/partly-cloudy-night.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/rain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/rain.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/sleet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/sleet.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/snow.png -------------------------------------------------------------------------------- /frontend/public/assets/weather/wind.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/assets/weather/wind.png -------------------------------------------------------------------------------- /frontend/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/public/favicon.ico -------------------------------------------------------------------------------- /frontend/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /frontend/static.json: -------------------------------------------------------------------------------- 1 | { 2 | "https_only": true 3 | } 4 | -------------------------------------------------------------------------------- /frontend/testem.js: -------------------------------------------------------------------------------- 1 | /*jshint node:true*/ 2 | module.exports = { 3 | "framework": "qunit", 4 | "test_page": "tests/index.html?hidepassed", 5 | "disable_watching": true, 6 | "launch_in_ci": [ 7 | "PhantomJS" 8 | ], 9 | "launch_in_dev": [ 10 | "PhantomJS", 11 | "Chrome" 12 | ], 13 | "proxies": { 14 | "/api": { 15 | "target": "http://localhost:3000" 16 | } 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /frontend/tests/helpers/destroy-app.js: -------------------------------------------------------------------------------- 1 | import { run } from '@ember/runloop'; 2 | 3 | export default function destroyApp(application) { 4 | run(application, 'destroy'); 5 | } 6 | -------------------------------------------------------------------------------- /frontend/tests/helpers/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from '../../resolver'; 2 | import config from '../../config/environment'; 3 | 4 | const resolver = Resolver.create(); 5 | 6 | resolver.namespace = { 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix 9 | }; 10 | 11 | export default resolver; 12 | -------------------------------------------------------------------------------- /frontend/tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import resolver from './helpers/resolver'; 2 | import Application from '../app'; 3 | import config from '../config/environment'; 4 | import { setApplication, setResolver } from '@ember/test-helpers'; 5 | import { start } from 'ember-qunit'; 6 | 7 | setApplication(Application.create(config.APP)); 8 | setResolver(resolver); 9 | 10 | start(); 11 | -------------------------------------------------------------------------------- /frontend/tests/unit/adapters/reaction-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('adapter:reaction', 'Unit | Adapter | reaction', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:session'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let adapter = this.subject(); 11 | assert.ok(adapter); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/controllers/notifications-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('controller:notifications', 'Unit | Controller | notifications', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let controller = this.subject(); 11 | assert.ok(controller); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/controllers/oracle/index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('controller:oracle/index', 'Unit | Controller | oracle/index', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll'], 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let controller = this.subject(); 11 | assert.ok(controller); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/controllers/posts/followings-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('controller:posts/followings', 'Unit | Controller | posts/followings', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let controller = this.subject(); 11 | assert.ok(controller); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/controllers/posts/index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('controller:posts/index', 'Unit | Controller | posts/index', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let controller = this.subject(); 11 | assert.ok(controller); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/controllers/posts/new-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('controller:posts/new', 'Unit | Controller | posts/new', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let controller = this.subject(); 11 | assert.ok(controller); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/controllers/posts/profile-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('controller:posts/profile', 'Unit | Controller | posts/profile', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:notifications'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let controller = this.subject(); 11 | assert.ok(controller); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/controllers/settings-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('controller:settings', 'Unit | Controller | settings', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let controller = this.subject(); 11 | assert.ok(controller); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/helpers/includes-test.js: -------------------------------------------------------------------------------- 1 | 2 | import { includes } from 'flaredown/helpers/includes'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Helper | includes'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | assert.notOk(includes([42])); 10 | assert.notOk(includes([42, 43])); 11 | assert.ok(includes([42, 42])); 12 | assert.ok(includes([42, 42, 43])); 13 | assert.ok(includes([42, 43, 42])); 14 | }); 15 | 16 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/add-meta-tags-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import AddMetaTagsMixin from 'flaredown/mixins/add-meta-tags'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | add meta tags'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let AddMetaTagsObject = Ember.Object.extend(AddMetaTagsMixin); 10 | let subject = AddMetaTagsObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/back-navigateable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import BackNavigateableMixin from 'flaredown/mixins/back-navigateable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | back navigateable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let BackNavigateableObject = Ember.Object.extend(BackNavigateableMixin); 10 | let subject = BackNavigateableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/body-formatable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import BodyFormatableMixin from 'flaredown/mixins/body-formatable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | body formatable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let BodyFormatableObject = Ember.Object.extend(BodyFormatableMixin); 10 | let subject = BodyFormatableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/fields-by-units-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import FieldsByUnitsMixin from 'flaredown/mixins/fields-by-units'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | fields by units'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let FieldsByUnitsObject = Ember.Object.extend(FieldsByUnitsMixin); 10 | let subject = FieldsByUnitsObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/history-trackable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import HistoryTrackableMixin from 'flaredown/mixins/history-trackable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | history trackable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let HistoryTrackableObject = Ember.Object.extend(HistoryTrackableMixin); 10 | let subject = HistoryTrackableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/navbar-searchable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import NavbarSearchableMixin from 'flaredown/mixins/navbar-searchable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | navbar searcheable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let NavbarSearchableObject = Ember.Object.extend(NavbarSearchableMixin); 10 | let subject = NavbarSearchableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/postable-getable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import PostableGetableMixin from 'flaredown/mixins/postable-getable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | postable getable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let PostableGetableObject = Ember.Object.extend(PostableGetableMixin); 10 | let subject = PostableGetableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/toggle-header-logo-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import ToggleHeaderLogoMixin from 'flaredown/mixins/toggle-header-logo'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | toggle header logo'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let ToggleHeaderLogoObject = Ember.Object.extend(ToggleHeaderLogoMixin); 10 | let subject = ToggleHeaderLogoObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/topicable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import TopicableMixin from 'flaredown/mixins/topicable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | topicable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let TopicableObject = Ember.Object.extend(TopicableMixin); 10 | let subject = TopicableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/typeable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import TypeableMixin from 'flaredown/mixins/typeable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | typeable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let TypeableObject = Ember.Object.extend(TypeableMixin); 10 | let subject = TypeableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/update-notifications-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UpdateNotificationsMixin from 'flaredown/mixins/update-notifications'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | update notifications'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let UpdateNotificationsObject = Ember.Object.extend(UpdateNotificationsMixin); 10 | let subject = UpdateNotificationsObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/mixins/user-nameable-test.js: -------------------------------------------------------------------------------- 1 | import Ember from 'ember'; 2 | import UserNameableMixin from 'flaredown/mixins/user-nameable'; 3 | import { module, test } from 'qunit'; 4 | 5 | module('Unit | Mixin | user nameable'); 6 | 7 | // Replace this with your real tests. 8 | test('it works', function(assert) { 9 | let UserNameableObject = Ember.Object.extend(UserNameableMixin); 10 | let subject = UserNameableObject.create(); 11 | assert.ok(subject); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/chart-list-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('chart-list', 'Unit | Model | chart list', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/comment-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('comment', 'Unit | Model | comment', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:post', 'model:reaction'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/food-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('food', 'Unit | Model | food', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/harvey-bradshaw-index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('harvey-bradshaw-index', 'Unit | Model | harvey bradshaw index', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:checkin'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/notification-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('notification', 'Unit | Model | notification', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/oracle-request-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('oracle-request', 'Unit | Model | oracle request', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:sex', 'model:symptom'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/pattern-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('pattern', 'Unit | Model | pattern', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/post-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('post', 'Unit | Model | post', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:tag', 'model:symptom', 'model:comment', 'model:condition', 'model:treatment', 'model:reaction'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/postable-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('postable', 'Unit | Model | postable', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:post', 'model:comment'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/reactable-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('reactable', 'Unit | Model | reactable', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:reaction'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/reaction-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('reaction', 'Unit | Model | reaction', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/session-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('session', 'Unit | Model | session', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/topic-following-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('topic-following', 'Unit | Model | topic following', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:tag', 'model:symptom', 'model:comment', 'model:condition', 'model:treatment'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/user-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('user', 'Unit | Model | user', { 4 | // Specify the other units that are required for this test. 5 | needs: ['model:profile', 'model:topic-following'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/models/weather-test.js: -------------------------------------------------------------------------------- 1 | import { moduleForModel, test } from 'ember-qunit'; 2 | 3 | moduleForModel('weather', 'Unit | Model | weather', { 4 | // Specify the other units that are required for this test. 5 | needs: [] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let model = this.subject(); 10 | // let store = this.store(); 11 | assert.ok(!!model); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/notifications-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:notifications', 'Unit | Route | notifications', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/oracle-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:oracle', 'Unit | Route | oracle', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/oracle/index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:oracle/index', 'Unit | Route | oracle/index', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/oracle/result-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:oracle/result', 'Unit | Route | oracle/result', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/posts-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:posts', 'Unit | Route | posts', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/posts/followings-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:posts/followings', 'Unit | Route | posts/followings', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/posts/index-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:posts/index', 'Unit | Route | posts/index', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/posts/new-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:posts/new', 'Unit | Route | posts/new', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/posts/profile-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:posts/profile', 'Unit | Route | posts/profile', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/posts/show-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:posts/show', 'Unit | Route | posts/show', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/posts/topic-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:posts/topic', 'Unit | Route | posts/topic', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/routes/settings-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('route:settings', 'Unit | Route | settings', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:router-scroll', 'service:route-history', 'service:session', 'service:ajax', 'service:notifications', 'service:logo-visiability'] 6 | }); 7 | 8 | test('it exists', function(assert) { 9 | let route = this.subject(); 10 | assert.ok(route); 11 | }); 12 | -------------------------------------------------------------------------------- /frontend/tests/unit/services/ajax-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('service:ajax', 'Unit | Service | ajax', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:session'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let service = this.subject(); 11 | assert.ok(service); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/services/emojis-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('service:emojis', 'Unit | Service | emojis', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['service:foo'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let service = this.subject(); 11 | assert.ok(service); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/services/logo-visiability-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('service:logo-visiability', 'Unit | Service | logo visiability', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['service:foo'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let service = this.subject(); 11 | assert.ok(service); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/services/notifications-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('service:notifications', 'Unit | Service | notifications', { 4 | // Specify the other units that are required for this test. 5 | needs: ['service:session'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let service = this.subject(); 11 | assert.ok(service); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/services/route-history-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('service:route-history', 'Unit | Service | route history', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['service:foo'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let service = this.subject(); 11 | assert.ok(service); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/transforms/raw-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('transform:raw', 'Unit | Transform | raw', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['serializer:foo'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let transform = this.subject(); 11 | assert.ok(transform); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/tests/unit/transforms/time-zone-name-test.js: -------------------------------------------------------------------------------- 1 | import { moduleFor, test } from 'ember-qunit'; 2 | 3 | moduleFor('transform:time-zone-name', 'Unit | Transform | time zone name', { 4 | // Specify the other units that are required for this test. 5 | // needs: ['serializer:foo'] 6 | }); 7 | 8 | // Replace this with your real tests. 9 | test('it exists', function(assert) { 10 | let transform = this.subject(); 11 | assert.ok(transform); 12 | }); 13 | -------------------------------------------------------------------------------- /frontend/vendor/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/frontend/vendor/.gitkeep -------------------------------------------------------------------------------- /native/.dockerignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | node_modules 3 | dist 4 | tmp 5 | .git 6 | README.md 7 | LICENSE 8 | .gitignore 9 | -------------------------------------------------------------------------------- /native/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ["universe/native"], 4 | }; 5 | -------------------------------------------------------------------------------- /native/.nvmrc: -------------------------------------------------------------------------------- 1 | v18.18.0 2 | -------------------------------------------------------------------------------- /native/AppEntry.js: -------------------------------------------------------------------------------- 1 | import registerRootComponent from "expo/build/launch/registerRootComponent"; 2 | 3 | import App from "./src/App"; 4 | 5 | registerRootComponent(App); 6 | -------------------------------------------------------------------------------- /native/assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/native/assets/adaptive-icon.png -------------------------------------------------------------------------------- /native/assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/native/assets/favicon.png -------------------------------------------------------------------------------- /native/assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/native/assets/icon.png -------------------------------------------------------------------------------- /native/assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rubyforgood/Flaredown/a5dae4eb9bfed7f8487e4bf008e9ff7003a8a5e1/native/assets/splash.png -------------------------------------------------------------------------------- /native/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function (api) { 2 | api.cache(true); 3 | return { 4 | presets: ["babel-preset-expo"], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /native/src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import { render, screen } from "@testing-library/react-native"; 2 | import React from "react"; 3 | 4 | import App from "../src/App"; 5 | 6 | jest.useFakeTimers(); 7 | 8 | describe("", () => { 9 | it("renders title", async () => { 10 | render(); 11 | 12 | expect(screen.getByText("Welcome to Flaredown")).toBeDefined(); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /native/src/Theme.ts: -------------------------------------------------------------------------------- 1 | import { DefaultTheme } from "react-native-paper"; 2 | 3 | export const Theme = { 4 | ...DefaultTheme, 5 | colors: { 6 | ...DefaultTheme.colors, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /native/src/components/Card.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet } from "react-native"; 3 | import { Card } from "react-native-paper"; 4 | 5 | export default function Background({ children }) { 6 | return {children}; 7 | } 8 | 9 | const styles = StyleSheet.create({ 10 | card: { 11 | padding: 30, 12 | width: "100%", 13 | maxWidth: 500, 14 | }, 15 | }); 16 | -------------------------------------------------------------------------------- /native/src/components/Header.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { StyleSheet } from "react-native"; 3 | import { Text } from "react-native-paper"; 4 | 5 | import { Theme } from "../Theme"; 6 | 7 | export default function Header(props) { 8 | return ; 9 | } 10 | 11 | const styles = StyleSheet.create({ 12 | header: { 13 | fontSize: 21, 14 | color: Theme.colors.primary, 15 | fontWeight: "bold", 16 | paddingVertical: 12, 17 | }, 18 | }); 19 | -------------------------------------------------------------------------------- /native/src/helpers/emailValidator.ts: -------------------------------------------------------------------------------- 1 | export function emailValidator(email) { 2 | const re = /\S+@\S+\.\S+/; 3 | if (!email) return "Email address is required."; 4 | if (!re.test(email)) return "Please enter a valid email address."; 5 | return ""; 6 | } 7 | -------------------------------------------------------------------------------- /native/src/helpers/passwordValidator.ts: -------------------------------------------------------------------------------- 1 | export function passwordValidator(password) { 2 | if (!password) return "Password is required."; 3 | if (password.length < 8) 4 | return "Password should contain at least 8 characters."; 5 | return ""; 6 | } 7 | -------------------------------------------------------------------------------- /native/src/helpers/usernameValidator.ts: -------------------------------------------------------------------------------- 1 | export function usernameValidator(name) { 2 | if (!name) return "Username is required."; 3 | return ""; 4 | } 5 | -------------------------------------------------------------------------------- /native/src/screens/Dashboard.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { View } from "react-native"; 3 | 4 | import Layout from "../components/Layout"; 5 | import Link from "../components/Link"; 6 | 7 | export default function Dashboard({ navigation }) { 8 | return ( 9 | 10 | 11 | navigation.replace("LoginScreen")}>Log out 12 | 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /native/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "jsx": "react" 4 | }, 5 | "extends": "expo/tsconfig.base" 6 | } 7 | -------------------------------------------------------------------------------- /script/backend: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")"/.. 4 | 5 | docker compose --profile dev run --rm backend $@ 6 | -------------------------------------------------------------------------------- /script/ember: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")"/.. 4 | 5 | docker compose --profile dev run --rm frontend ./node_modules/.bin/ember $@ 6 | -------------------------------------------------------------------------------- /script/frontend: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")"/.. 4 | 5 | docker compose --profile dev run --rm frontend $@ 6 | -------------------------------------------------------------------------------- /script/npm: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname "$0")"/.. 4 | 5 | docker compose --profile dev run --rm frontend npm $@ 6 | --------------------------------------------------------------------------------