diff --git a/CHANGELOG.md b/CHANGELOG.md index 0cd6b538e..02eaa9eb0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,17 @@ ## Next release - [TODO DEPLOY] `rails fablab:stripe:set_gateway` +## v4.7.4 2021 March 08 +- Show remaining training credits in the dashboard +- Allow writing short rich descriptions for each subscription plan +- Allow inserting hyperlinks in customized info messages +- Use the primary color to display plans' price in the public view +- Do not close login modal when clicking on the backdrop +- Improved scripts for mounting volumes +- Increased verbosity of upgrade script +- Fix a bug: mounting the payment-schedules volume in the docker-compose file results in an invalid file +- [TODO DEPLOY] `rails fablab:maintenance:rebuild_stylesheet` + ## v4.7.3 2021 March 03 - Improved the setup script - Fix a bug: unable to install a new instance with an external reverse proxy diff --git a/app/controllers/api/plans_controller.rb b/app/controllers/api/plans_controller.rb index e0d1769de..7e15e5015 100644 --- a/app/controllers/api/plans_controller.rb +++ b/app/controllers/api/plans_controller.rb @@ -68,7 +68,7 @@ class API::PlansController < API::ApiController @parameters = @parameters.require(:plan) .permit(:base_name, :type, :group_id, :amount, :interval, :interval_count, :is_rolling, - :training_credit_nb, :ui_weight, :disabled, :monthly_payment, + :training_credit_nb, :ui_weight, :disabled, :monthly_payment, :description, plan_file_attributes: %i[id attachment _destroy], prices_attributes: %i[id amount]) end diff --git a/app/frontend/src/javascript/components/plan-card.tsx b/app/frontend/src/javascript/components/plan-card.tsx index e6a1beb26..2911e8e12 100644 --- a/app/frontend/src/javascript/components/plan-card.tsx +++ b/app/frontend/src/javascript/components/plan-card.tsx @@ -71,6 +71,12 @@ const PlanCard: React.FC = ({ plan, userId, subscribedPlanId, ope const hasAttachment = (): boolean => { return !!plan.plan_file_url; } + /** + * Check if the plan has a description + */ + const hasDescription = (): boolean => { + return !!plan.description; + } /** * Check if the plan is allowing a monthly payment schedule */ @@ -100,25 +106,28 @@ const PlanCard: React.FC = ({ plan, userId, subscribedPlanId, ope } - {canSubscribeForMe() &&
- {!hasSubscribedToThisPlan() && } - {hasSubscribedToThisPlan() && } -
} - {canSubscribeForOther() &&
- -
} - {hasAttachment() && { t('app.public.plans.more_information') }} +
+ {hasDescription() &&
} + {hasAttachment() && { t('app.public.plans.more_information') }} + {canSubscribeForMe() &&
+ {!hasSubscribedToThisPlan() && } + {hasSubscribedToThisPlan() && } +
} + {canSubscribeForOther() &&
+ +
} +
); } diff --git a/app/frontend/src/javascript/controllers/admin/plans.js b/app/frontend/src/javascript/controllers/admin/plans.js index 9172956ab..bc230b43d 100644 --- a/app/frontend/src/javascript/controllers/admin/plans.js +++ b/app/frontend/src/javascript/controllers/admin/plans.js @@ -64,6 +64,14 @@ class PlanController { return file._destroy = true; } }; + + /** + * Check and limit + * @param content + */ + $scope.limitDescriptionSize = function (content) { + alert(content); + }; } } diff --git a/app/frontend/src/javascript/controllers/application.js.erb b/app/frontend/src/javascript/controllers/application.js.erb index 9e9a58de0..c25601eb5 100644 --- a/app/frontend/src/javascript/controllers/application.js.erb +++ b/app/frontend/src/javascript/controllers/application.js.erb @@ -408,6 +408,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco <% else %> return $uibModal.open({ templateUrl: '/shared/deviseModal.html', + backdrop: 'static', size: 'sm', resolve: { settingsPromise: ['Setting', function (Setting) { return Setting.query({ names: "['confirmation_required']" }).$promise; }] diff --git a/app/frontend/src/javascript/controllers/dashboard.js b/app/frontend/src/javascript/controllers/dashboard.js index 6f2741898..aa908849c 100644 --- a/app/frontend/src/javascript/controllers/dashboard.js +++ b/app/frontend/src/javascript/controllers/dashboard.js @@ -12,7 +12,7 @@ */ 'use strict'; -Application.Controllers.controller('DashboardController', ['$scope', 'memberPromise', 'SocialNetworks', function ($scope, memberPromise, SocialNetworks) { +Application.Controllers.controller('DashboardController', ['$scope', 'memberPromise', 'trainingsPromise', 'SocialNetworks', function ($scope, memberPromise, trainingsPromise, SocialNetworks) { // Current user's profile $scope.user = memberPromise; @@ -22,6 +22,24 @@ Application.Controllers.controller('DashboardController', ['$scope', 'memberProm networks: SocialNetworks }; + /** + * Check if the member has used his training credits for the given credit + * @param trainingCredits array of credits used by the member + * @param trainingId id of the training to find + */ + $scope.hasUsedTrainingCredit = function (trainingCredits, trainingId) { + return trainingCredits.find(tc => tc.training_id === trainingId); + }; + + /** + * Return the name associated with the provided training ID + * @param trainingId training identifier + * @return {string} + */ + $scope.getTrainingName = function (trainingId) { + return trainingsPromise.find(t => t.id === trainingId).name; + }; + /* PRIVATE SCOPE */ /** diff --git a/app/frontend/src/javascript/router.js b/app/frontend/src/javascript/router.js index 38dc021b9..c6dfb5702 100644 --- a/app/frontend/src/javascript/router.js +++ b/app/frontend/src/javascript/router.js @@ -143,7 +143,8 @@ angular.module('application.router', ['ui.router']) abstract: true, url: '/dashboard', resolve: { - memberPromise: ['Member', 'currentUser', function (Member, currentUser) { return Member.get({ id: currentUser.id }).$promise; }] + memberPromise: ['Member', 'currentUser', function (Member, currentUser) { return Member.get({ id: currentUser.id }).$promise; }], + trainingsPromise: ['Training', function (Training) { return Training.query().$promise; }] } }) .state('app.logged.dashboard.profile', { diff --git a/app/frontend/src/stylesheets/app.components.scss b/app/frontend/src/stylesheets/app.components.scss index 7c1a082e4..3d52a94c2 100644 --- a/app/frontend/src/stylesheets/app.components.scss +++ b/app/frontend/src/stylesheets/app.components.scss @@ -269,6 +269,7 @@ .pricing-panel { border: 1px solid $border-color; + height: 391px; &:first-child { border-right: none; @@ -280,6 +281,13 @@ @include border-radius(0 3px 3px 0); } + .plan-card { + height: 100%; + display: flex; + flex-direction: column; + justify-content: flex-start; + } + .title { margin: 10px 0; font-size: rem-calc(16); @@ -347,27 +355,39 @@ } } - .cta-button { - margin: 20px 0; + .card-footer { + display: flex; + flex-direction: column; + justify-content: space-around; + height: 100%; - .subscribe-button { - @extend .btn; - @extend .rounded; + .plan-description { + max-height: 5.2em; + overflow: hidden; + } - outline: 0; - font-weight: 600; - font-size: rem-calc(16); - background-color: white; - padding-left: 30px; - padding-right: 30px; + .cta-button { + margin: 20px 0; + + .subscribe-button { + @extend .btn; + @extend .rounded; + + outline: 0; + font-weight: 600; + font-size: rem-calc(16); + background-color: white; + padding-left: 30px; + padding-right: 30px; + } + button.subscribe-button:focus, button.subscribe-button:hover { + outline: 0; + } } - button.subscribe-button:focus, button.subscribe-button:hover { - outline: 0; + .info-link { + margin-top: 1em; } } - .info-link { - margin-top: 1em; - } } .well { @@ -800,3 +820,15 @@ input[type=date].form-control { margin-left: 1em; } } + +.medium-editor-input { + display: table-cell; + border: 1px solid #c0c0c0; + border-radius: 0.2em; + padding: 0.5em; + width: 100%; + + p { + margin-bottom: 0; + } +} diff --git a/app/frontend/src/stylesheets/app.layout.scss b/app/frontend/src/stylesheets/app.layout.scss index fe62d9d64..549bda911 100644 --- a/app/frontend/src/stylesheets/app.layout.scss +++ b/app/frontend/src/stylesheets/app.layout.scss @@ -686,3 +686,18 @@ body.container { text-align: center; vertical-align: middle; } + +.plan-description-input .medium-editor-input div[medium-editor] { + max-height: 5.2em; + overflow: hidden; + + & p:nth-child(2n+3), p:nth-child(2n+4) { + display: none; + } +} + +.close-modal-button { + position: absolute; + right: 13px; + cursor: pointer; +} diff --git a/app/frontend/templates/admin/plans/_form.html b/app/frontend/templates/admin/plans/_form.html index b40c91a02..7161b264e 100644 --- a/app/frontend/templates/admin/plans/_form.html +++ b/app/frontend/templates/admin/plans/_form.html @@ -127,6 +127,17 @@ {{ 'app.shared.plan.monthly_payment_info' }} +
+ +
+
+
+
+ +
+ diff --git a/app/frontend/templates/admin/settings/general.html b/app/frontend/templates/admin/settings/general.html index d2cbefa19..23c61d3c8 100644 --- a/app/frontend/templates/admin/settings/general.html +++ b/app/frontend/templates/admin/settings/general.html @@ -49,7 +49,7 @@

{{ 'app.admin.settings.message_of_the_machine_booking_page' }}

@@ -58,7 +58,7 @@

{{ 'app.admin.settings.warning_message_of_the_training_booking_page'}}

@@ -67,7 +67,7 @@

{{ 'app.admin.settings.information_message_of_the_training_reservation_page'}}

@@ -76,7 +76,7 @@

{{ 'app.admin.settings.message_of_the_subscriptions_page' }}

@@ -84,7 +84,7 @@

{{ 'app.admin.settings.message_of_the_events_page' }}

@@ -92,7 +92,7 @@

{{ 'app.admin.settings.message_of_the_spaces_page' }}

diff --git a/app/frontend/templates/dashboard/trainings.html b/app/frontend/templates/dashboard/trainings.html index 754839adb..6209b0a3b 100644 --- a/app/frontend/templates/dashboard/trainings.html +++ b/app/frontend/templates/dashboard/trainings.html @@ -7,11 +7,33 @@ +
+
+
+
+

{{ 'app.logged.dashboard.trainings.your_training_credits' | translate }}

+
+
+ {{ 'app.logged.dashboard.trainings.subscribe_for_credits' }} + {{ 'app.logged.dashboard.trainings.register_for_free' }} +
    +
  • + {{getTrainingName(c.training_id)}} + +
  • +
+
+
+
+
+
-
+

{{ 'app.logged.dashboard.trainings.your_next_trainings' | translate }}

diff --git a/app/frontend/templates/shared/deviseModal.html b/app/frontend/templates/shared/deviseModal.html index ef8b95187..11e946442 100644 --- a/app/frontend/templates/shared/deviseModal.html +++ b/app/frontend/templates/shared/deviseModal.html @@ -1,6 +1,7 @@