diff --git a/app/controllers/api/cart_controller.rb b/app/controllers/api/cart_controller.rb index d97c21a78..15dd592b8 100644 --- a/app/controllers/api/cart_controller.rb +++ b/app/controllers/api/cart_controller.rb @@ -2,12 +2,16 @@ # API Controller for manage user's cart class API::CartController < API::ApiController - before_action :current_order + before_action :current_order, except: %i[create] before_action :ensure_order, except: %i[create] def create authorize :cart, :create? - @order = current_order if current_order.present? + @order = Order.find_by(token: order_token) + @order = Order.find_by(statistic_profile_id: current_user.statistic_profile.id, state: 'cart') if @order.nil? && current_user&.member? + if @order && @order.statistic_profile_id.nil? && current_user&.member? + @order.update(statistic_profile_id: current_user.statistic_profile.id) + end @order ||= Cart::CreateService.new.call(current_user) render 'api/orders/show' end @@ -19,13 +23,13 @@ class API::CartController < API::ApiController end def remove_item - authorize :cart, policy_class: CartPolicy + authorize @current_order, policy_class: CartPolicy @order = Cart::RemoveItemService.new.call(@current_order, orderable) render 'api/orders/show' end def set_quantity - authorize :cart, policy_class: CartPolicy + authorize @current_order, policy_class: CartPolicy @order = Cart::SetQuantityService.new.call(@current_order, orderable, cart_params[:quantity]) render 'api/orders/show' end diff --git a/app/frontend/src/javascript/components/cart/store-cart.tsx b/app/frontend/src/javascript/components/cart/store-cart.tsx index 1ac2c7a2b..d24adffc2 100644 --- a/app/frontend/src/javascript/components/cart/store-cart.tsx +++ b/app/frontend/src/javascript/components/cart/store-cart.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import { react2angular } from 'react2angular'; import { Loader } from '../base/loader'; @@ -7,20 +7,28 @@ import { FabButton } from '../base/fab-button'; import useCart from '../../hooks/use-cart'; import FormatLib from '../../lib/format'; import CartAPI from '../../api/cart'; +import { User } from '../../models/user'; declare const Application: IApplication; interface StoreCartProps { onError: (message: string) => void, + currentUser: User, } /** * This component shows user's cart */ -const StoreCart: React.FC = ({ onError }) => { +const StoreCart: React.FC = ({ onError, currentUser }) => { const { t } = useTranslation('public'); - const { cart, setCart } = useCart(); + const { cart, setCart, reloadCart } = useCart(); + + useEffect(() => { + if (currentUser) { + reloadCart(); + } + }, [currentUser]); /** * Remove the product from cart @@ -79,12 +87,12 @@ const StoreCart: React.FC = ({ onError }) => { ); }; -const StoreCartWrapper: React.FC = ({ onError }) => { +const StoreCartWrapper: React.FC = (props) => { return ( - + ); }; -Application.Components.component('storeCart', react2angular(StoreCartWrapper, ['onError'])); +Application.Components.component('storeCart', react2angular(StoreCartWrapper, ['onError', 'currentUser'])); diff --git a/app/frontend/src/javascript/components/store/store.tsx b/app/frontend/src/javascript/components/store/store.tsx index e93789487..5cf4a7e30 100644 --- a/app/frontend/src/javascript/components/store/store.tsx +++ b/app/frontend/src/javascript/components/store/store.tsx @@ -9,20 +9,22 @@ import ProductAPI from '../../api/product'; import { StoreProductItem } from './store-product-item'; import useCart from '../../hooks/use-cart'; import { emitCustomEvent } from 'react-custom-events'; +import { User } from '../../models/user'; declare const Application: IApplication; interface StoreProps { onError: (message: string) => void, + currentUser: User, } /** * This component shows public store */ -const Store: React.FC = ({ onError }) => { +const Store: React.FC = ({ onError, currentUser }) => { const { t } = useTranslation('public'); - const { cart, setCart } = useCart(); + const { cart, setCart, reloadCart } = useCart(); const [products, setProducts] = useState>([]); @@ -38,6 +40,12 @@ const Store: React.FC = ({ onError }) => { emitCustomEvent('CartUpdate', cart); }, [cart]); + useEffect(() => { + if (currentUser) { + reloadCart(); + } + }, [currentUser]); + return (
@@ -85,12 +93,12 @@ const Store: React.FC = ({ onError }) => { ); }; -const StoreWrapper: React.FC = ({ onError }) => { +const StoreWrapper: React.FC = (props) => { return ( - + ); }; -Application.Components.component('store', react2angular(StoreWrapper, ['onError'])); +Application.Components.component('store', react2angular(StoreWrapper, ['onError', 'currentUser'])); diff --git a/app/frontend/src/javascript/controllers/application.js b/app/frontend/src/javascript/controllers/application.js index 93d9e6c1e..d2ae5b337 100644 --- a/app/frontend/src/javascript/controllers/application.js +++ b/app/frontend/src/javascript/controllers/application.js @@ -1,6 +1,6 @@ -Application.Controllers.controller('ApplicationController', ['$rootScope', '$scope', '$transitions', '$window', '$locale', '$timeout', 'Session', 'AuthService', 'Auth', '$uibModal', '$state', 'growl', 'Notification', '$interval', 'Setting', '_t', 'Version', 'Help', - function ($rootScope, $scope, $transitions, $window, $locale, $timeout, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t, Version, Help) { +Application.Controllers.controller('ApplicationController', ['$rootScope', '$scope', '$transitions', '$window', '$locale', '$timeout', 'Session', 'AuthService', 'Auth', '$uibModal', '$state', 'growl', 'Notification', '$interval', 'Setting', '_t', 'Version', 'Help', '$cookies', + function ($rootScope, $scope, $transitions, $window, $locale, $timeout, Session, AuthService, Auth, $uibModal, $state, growl, Notification, $interval, Setting, _t, Version, Help, $cookies) { /* PRIVATE STATIC CONSTANTS */ // User's notifications will get refreshed every 30s @@ -58,6 +58,7 @@ Application.Controllers.controller('ApplicationController', ['$rootScope', '$sco total: 0, unread: 0 }; + $cookies.remove('fablab_cart_token'); return $state.go('app.public.home'); }, function (error) { console.error(`An error occurred logging out: ${error}`); diff --git a/app/frontend/src/javascript/hooks/use-cart.ts b/app/frontend/src/javascript/hooks/use-cart.ts index 587647ff2..bd7d8382f 100644 --- a/app/frontend/src/javascript/hooks/use-cart.ts +++ b/app/frontend/src/javascript/hooks/use-cart.ts @@ -25,5 +25,13 @@ export default function useCart () { } }, []); - return { loading, cart, error, setCart }; + const reloadCart = async () => { + setLoading(true); + const currentCartToken = getCartToken(); + const data = await CartAPI.create(currentCartToken); + setCart(data); + setLoading(false); + }; + + return { loading, cart, error, setCart, reloadCart }; } diff --git a/app/frontend/templates/cart/index.html b/app/frontend/templates/cart/index.html index 7f783a09c..75c73bbed 100644 --- a/app/frontend/templates/cart/index.html +++ b/app/frontend/templates/cart/index.html @@ -15,5 +15,5 @@
- +
diff --git a/app/frontend/templates/store/index.html b/app/frontend/templates/store/index.html index 20d00a606..fd39e9d62 100644 --- a/app/frontend/templates/store/index.html +++ b/app/frontend/templates/store/index.html @@ -21,5 +21,5 @@
- +
diff --git a/app/policies/cart_policy.rb b/app/policies/cart_policy.rb index 34ebb43ae..0aad87849 100644 --- a/app/policies/cart_policy.rb +++ b/app/policies/cart_policy.rb @@ -8,7 +8,9 @@ class CartPolicy < ApplicationPolicy %w[add_item remove_item set_quantity].each do |action| define_method "#{action}?" do - user.privileged? || (record.statistic_profile.user_id == user.id) + return user.privileged? || (record.statistic_profile_id == user.statistic_profile.id) if user + + record.statistic_profile_id.nil? end end end