diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 55205328..50933fd1 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -1,18 +1,38 @@
# frozen_string_literal: true
class UsersController < ApplicationController
- before_action :set_user, only: %i[show]
+ layout 'backoffice'
+ before_action :set_user
+ before_action :verify_current_user
# GET /users/1
# GET /users/1.json
def show
- redirect_to root_path unless current_user == @user
+ current_page_title('Your dashboard')
+ end
+
+ # pages
+ def subscription
+ current_page_title('Subscription management')
@is_subscription_changing = UserPlanChange.where(user_id: @user.id, status: 'pending').first
end
+ def donation_history
+ current_page_title('Donation history')
+ end
+
private
+ def current_page_title(page_title)
+ @current_page_title ||= page_title
+ end
+
+ def verify_current_user
+ redirect_to root_path unless current_user == @user
+ end
+
def set_user
- @user = User.find(params[:id])
+ user_param_id = params[:id] || params[:user_id]
+ @user = User.find(user_param_id)
end
end
diff --git a/app/javascript/bundles/User/components/Drawer.jsx b/app/javascript/bundles/User/components/Drawer.jsx
new file mode 100644
index 00000000..7bd74afe
--- /dev/null
+++ b/app/javascript/bundles/User/components/Drawer.jsx
@@ -0,0 +1,159 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import AppBar from '@material-ui/core/AppBar'
+import CssBaseline from '@material-ui/core/CssBaseline'
+import Divider from '@material-ui/core/Divider'
+import Drawer from '@material-ui/core/Drawer'
+import Hidden from '@material-ui/core/Hidden'
+import IconButton from '@material-ui/core/IconButton'
+import List from '@material-ui/core/List'
+import ListItem from '@material-ui/core/ListItem'
+import ListItemIcon from '@material-ui/core/ListItemIcon'
+import ListItemText from '@material-ui/core/ListItemText'
+import UsersIcon from '@material-ui/icons/SupervisedUserCircle'
+import BookIcon from '@material-ui/icons/Book'
+import SubscriptionsIcon from '@material-ui/icons/Subscriptions'
+import MenuIcon from '@material-ui/icons/Menu'
+import Toolbar from '@material-ui/core/Toolbar'
+import Typography from '@material-ui/core/Typography'
+import { makeStyles, useTheme } from '@material-ui/core/styles'
+
+const drawerWidth = 240
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ display: 'flex'
+ },
+ drawer: {
+ [theme.breakpoints.up('sm')]: {
+ width: drawerWidth,
+ flexShrink: 0
+ }
+ },
+ appBar: {
+ marginLeft: drawerWidth,
+ [theme.breakpoints.up('sm')]: {
+ width: `calc(100% - ${drawerWidth}px)`
+ }
+ },
+ menuButton: {
+ marginRight: theme.spacing(2),
+ [theme.breakpoints.up('sm')]: {
+ display: 'none'
+ }
+ },
+ toolbar: theme.mixins.toolbar,
+ drawerPaper: {
+ width: drawerWidth
+ },
+ content: {
+ flexGrow: 1,
+ padding: theme.spacing(3)
+ }
+}))
+
+function ResponsiveDrawer (props) {
+ const { container } = props
+ const classes = useStyles()
+ const theme = useTheme()
+ const [mobileOpen, setMobileOpen] = React.useState(false)
+
+ function handleDrawerToggle () {
+ setMobileOpen(!mobileOpen)
+ }
+
+ const drawer = (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+
+ return (
+
+
+
+
+
+
+
+
+ {props.pageTitle}
+
+
+
+
+
+ )
+}
+
+ResponsiveDrawer.propTypes = {
+ pageTitle: PropTypes.string.isRequired,
+ user: PropTypes.object.isRequired
+}
+
+export default props =>
diff --git a/app/javascript/packs/user-bundle.js b/app/javascript/packs/user-bundle.js
index d43bcb42..81873eba 100644
--- a/app/javascript/packs/user-bundle.js
+++ b/app/javascript/packs/user-bundle.js
@@ -4,10 +4,12 @@ import { UserShow } from '../bundles/User/components/UserShow'
import { DonationsHistory } from '../bundles/User/components/DonationsHistory'
import { SubscriptionCancel } from '../bundles/User/components/SubscriptionCancel'
import { CurrentPlan } from '../bundles/User/components/CurrentPlan'
+import Drawer from '../bundles/User/components/Drawer'
ReactOnRails.register({
UserShow,
DonationsHistory,
SubscriptionCancel,
- CurrentPlan
+ CurrentPlan,
+ Drawer
})
diff --git a/app/views/layouts/backoffice.html.erb b/app/views/layouts/backoffice.html.erb
new file mode 100644
index 00000000..60c477f0
--- /dev/null
+++ b/app/views/layouts/backoffice.html.erb
@@ -0,0 +1,35 @@
+
+
+
+ Fundraising
+
+ <%= csrf_meta_tags %>
+ <%= csp_meta_tag %>
+ <%= content_for?(:head) ? yield(:head) : '' %>
+
+ <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
+
+ <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
+ <%= javascript_include_tag 'https://checkout.stripe.com/checkout.js' %>
+ <%= javascript_include_tag 'https://js.stripe.com/v3/' %>
+ <%= javascript_pack_tag 'user-bundle' %>
+
+
+
+
+
+
+
+
+
+
+
+
+ <%= react_component("Drawer", props: {pageTitle: @current_page_title, user: @user}) %>
+
+
+ <%= yield %>
+
+
+
+
diff --git a/app/views/users/donation_history.html.erb b/app/views/users/donation_history.html.erb
new file mode 100644
index 00000000..bd79940b
--- /dev/null
+++ b/app/views/users/donation_history.html.erb
@@ -0,0 +1,5 @@
+
+ <%= notice %>
+
+ <%= react_component("DonationsHistory", props: {donations: @user.donations}) %>
+
diff --git a/app/views/users/show.html.erb b/app/views/users/show.html.erb
index 9701ea85..2a544ce2 100644
--- a/app/views/users/show.html.erb
+++ b/app/views/users/show.html.erb
@@ -2,6 +2,4 @@
<%= notice %>
<%= react_component("UserShow", props: {user: @user, streak: @user.current_streak, subscription: @user.active_subscription}) %>
- <%= react_component("SubscriptionCancel", props: {user: @user, subscription: @user.active_subscription, activePlan: @user.active_subscription&.plan, isSubscriptionChanging: @is_subscription_changing}) %>
- <%= react_component("DonationsHistory", props: {donations: @user.donations}) %>
diff --git a/app/views/users/subscription.html.erb b/app/views/users/subscription.html.erb
new file mode 100644
index 00000000..ec5e6384
--- /dev/null
+++ b/app/views/users/subscription.html.erb
@@ -0,0 +1,5 @@
+
+ <%= notice %>
+
+ <%= react_component("SubscriptionCancel", props: {user: @user, subscription: @user.active_subscription, activePlan: @user.active_subscription&.plan, isSubscriptionChanging: @is_subscription_changing}) %>
+
diff --git a/config/routes.rb b/config/routes.rb
index 66aade7d..dc59b876 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -19,6 +19,8 @@
end
resources :users, only: %i[show new edit update create destroy] do
+ get '/subscription' => 'users#subscription', as: :current_subscription
+ get '/donations' => 'users#donation_history', as: :latest_donations
resource :streak, only: %i[show]
resources :cards, only: %i[index destroy]
resource :subscription, only: %i[destroy]
diff --git a/spec/features/plan_change_spec.rb b/spec/features/plan_change_spec.rb
index 42f8175c..6924f08c 100644
--- a/spec/features/plan_change_spec.rb
+++ b/spec/features/plan_change_spec.rb
@@ -16,6 +16,9 @@
within '#contact-data' do
expect(page).to have_content(user.name)
end
+
+ visit user_current_subscription_path(user)
+
expect(page).to have_content("You're subscribed")
click_link 'Change Subscription'
diff --git a/spec/features/user/users_profile_spec.rb b/spec/features/user/users_profile_spec.rb
index 7d983b18..d606f6d1 100644
--- a/spec/features/user/users_profile_spec.rb
+++ b/spec/features/user/users_profile_spec.rb
@@ -3,49 +3,43 @@
require 'rails_helper'
describe 'User - manages their profile', type: :feature, js: true do
- describe 'home' do
- let!(:user) { FactoryBot.create(:user) }
- let!(:subscription) { FactoryBot.create(:subscription, user_id: user.id, active: true) }
- let!(:one_time_donations) { FactoryBot.create_list(:donation, 5, user_id: user.id, donation_type: Donation::DONATION_TYPES[:one_off]) }
+ let!(:user) { FactoryBot.create(:user) }
+ let!(:subscription) { FactoryBot.create(:subscription, user_id: user.id, active: true) }
+ let!(:one_time_donations) { FactoryBot.create_list(:donation, 5, user_id: user.id, donation_type: Donation::DONATION_TYPES[:one_off]) }
- before(:each) do
- allow_any_instance_of(SessionProvider).to receive(:current_user).and_return(user)
- end
-
- it 'can view their subscription and donation history' do
- 5.times do
- donation = FactoryBot.create(:donation, user_id: user.id)
- FactoryBot.create(:subscription_donation, subscription_id: subscription.id, donation_id: donation.id)
- end
- visit user_path(user)
- expect(page).to have_content(user.name)
- expect(page).to have_content(user.email)
-
- expect(page).to have_content(subscription.plan.name)
+ before(:each) do
+ allow_any_instance_of(SessionProvider).to receive(:current_user).and_return(user)
+ end
- user.donations.each do |donation|
- expect(page).to have_content(donation.amount)
- end
+ it 'can view their subscription and donation history' do
+ 5.times do
+ donation = FactoryBot.create(:donation, user_id: user.id)
+ FactoryBot.create(:subscription_donation, subscription_id: subscription.id, donation_id: donation.id)
end
+ visit user_latest_donations_path(user)
+ expect(page).to have_content('Your Donations History')
- it 'can cancel an active subscription' do
- expect(subscription.active).to eq(true)
- visit user_path(user)
- expect(page).to have_content(user.name)
- expect(page).to have_content(user.email)
+ user.donations.each do |donation|
+ expect(page).to have_content(donation.amount)
+ end
+ end
- expect(page).to have_content(subscription.plan.name)
+ it 'can cancel an active subscription' do
+ expect(subscription.active).to eq(true)
+ visit user_current_subscription_path(user)
+ expect(page).to have_content("You're subscribed")
- click_button 'Cancel Subscription'
+ expect(page).to have_content(subscription.plan.name)
- expect(page).to have_content('Do you want to terminate your current subscription?')
- within '#cancel-subscription-dialog' do
- click_button 'Cancel Subscription'
- end
+ click_button 'Cancel Subscription'
- expect(page).to have_content('No active subscription')
- subscription.reload
- expect(subscription.active).to eq(false)
+ expect(page).to have_content('Do you want to terminate your current subscription?')
+ within '#cancel-subscription-dialog' do
+ click_button 'Cancel Subscription'
end
+
+ expect(page).to have_content('No active subscription')
+ subscription.reload
+ expect(subscription.active).to eq(false)
end
end