account preferences page
new page to change user's recording preferences
This commit is contained in:
parent
3677181e09
commit
5ff152233b
|
|
@ -0,0 +1,34 @@
|
||||||
|
/// <reference types="cypress" />
|
||||||
|
|
||||||
|
import makeFakeUser from '../../factories/user';
|
||||||
|
|
||||||
|
describe('Account Preferences Feature', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
// Log in to the application or navigate to the account page
|
||||||
|
// where the change email feature is available
|
||||||
|
const currentUser = makeFakeUser({
|
||||||
|
email: 'sam@example.com',
|
||||||
|
recording_pref: 0
|
||||||
|
});
|
||||||
|
cy.stubAuthenticate({ ...currentUser });
|
||||||
|
cy.intercept('POST', /\S+\/users\S+/, {
|
||||||
|
statusCode: 200
|
||||||
|
}).as('updateUser');
|
||||||
|
cy.visit('/account/preferences');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display the current recording preference', () => {
|
||||||
|
// Assert that the current recording preference is displayed
|
||||||
|
cy.get('[data-testid=recording_pref_none]').should('be.checked');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should save the new recording preference', () => {
|
||||||
|
// Select a new recording preference
|
||||||
|
cy.get('[data-testid=recording_pref_my_audio]').check('1');
|
||||||
|
cy.wait('@updateUser');
|
||||||
|
// Assert that the new recording preference is saved
|
||||||
|
cy.contains('Recording preference saved successfully.');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
|
@ -37,6 +37,7 @@ import JKEditProfile from '../page/JKEditProfile';
|
||||||
import JKEditAccount from '../page/JKEditAccount';
|
import JKEditAccount from '../page/JKEditAccount';
|
||||||
import JKAccountSubscription from '../page/JKAccountSubscription';
|
import JKAccountSubscription from '../page/JKAccountSubscription';
|
||||||
import JKPaymentHistory from '../page/JKPaymentHistory';
|
import JKPaymentHistory from '../page/JKPaymentHistory';
|
||||||
|
import JKAccountPreferences from '../page/JKAccountPreferences';
|
||||||
|
|
||||||
import JKAffiliateProgram from '../affiliate/JKAffiliateProgram';
|
import JKAffiliateProgram from '../affiliate/JKAffiliateProgram';
|
||||||
import JKAffiliatePayee from '../affiliate/JKAffiliatePayee';
|
import JKAffiliatePayee from '../affiliate/JKAffiliatePayee';
|
||||||
|
|
@ -294,6 +295,7 @@ function JKDashboardMain() {
|
||||||
<PrivateRoute path="/account/identity" component={JKEditAccount} />
|
<PrivateRoute path="/account/identity" component={JKEditAccount} />
|
||||||
<PrivateRoute path="/account/subscription" component={JKAccountSubscription} />
|
<PrivateRoute path="/account/subscription" component={JKAccountSubscription} />
|
||||||
<PrivateRoute path="/account/payments" component={JKPaymentHistory} />
|
<PrivateRoute path="/account/payments" component={JKPaymentHistory} />
|
||||||
|
<PrivateRoute path="/account/preferences" component={JKAccountPreferences} />
|
||||||
<PrivateRoute path="/affiliate/program" component={JKAffiliateProgram} />
|
<PrivateRoute path="/affiliate/program" component={JKAffiliateProgram} />
|
||||||
<PrivateRoute path="/affiliate/payee" component={JKAffiliatePayee} />
|
<PrivateRoute path="/affiliate/payee" component={JKAffiliatePayee} />
|
||||||
<PrivateRoute path="/affiliate/links" component={JKAffiliateLinks} />
|
<PrivateRoute path="/affiliate/links" component={JKAffiliateLinks} />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
import React, { useState, useEffect } from 'react'
|
||||||
|
import { Row, Col, Card, CardHeader, CardBody, Form, FormGroup, Label, Input } from 'reactstrap';
|
||||||
|
import FalconCardHeader from '../common/FalconCardHeader';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { useAuth } from '../../context/UserAuth';
|
||||||
|
import { updateUser } from '../../helpers/rest';
|
||||||
|
import { toast } from 'react-toastify';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
|
||||||
|
const JKAccountPreferences = () => {
|
||||||
|
const { t } = useTranslation('account');
|
||||||
|
const { currentUser } = useAuth();
|
||||||
|
const [selectedPref, setSelectedPref] = useState(null);
|
||||||
|
const [selectedPrefV2, setSelectedPrefV2] = useState(null);
|
||||||
|
|
||||||
|
const {
|
||||||
|
register,
|
||||||
|
setValue
|
||||||
|
} = useForm();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (currentUser) {
|
||||||
|
setValue('recording_pref', currentUser.recording_pref);
|
||||||
|
setSelectedPrefV2(currentUser.recording_pref);
|
||||||
|
}
|
||||||
|
}, [currentUser]);
|
||||||
|
|
||||||
|
//save the selected preference to the database
|
||||||
|
useEffect(() => {
|
||||||
|
if (!currentUser || selectedPref === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
recording_pref: selectedPref
|
||||||
|
}
|
||||||
|
|
||||||
|
updateUser(currentUser.id, params).then(response => {
|
||||||
|
setSelectedPrefV2(selectedPref);
|
||||||
|
toast.success(t('preferences.recording_preferences.save_success'));
|
||||||
|
}).catch(error => {
|
||||||
|
console.log(error);
|
||||||
|
toast.error(t('preferences.recording_preferences.save_error'));
|
||||||
|
});
|
||||||
|
|
||||||
|
}, [selectedPref]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card>
|
||||||
|
<FalconCardHeader title={t('preferences.page_title')} titleClass="font-weight-bold" />
|
||||||
|
<CardBody className="pt-3" style={{ backgroundColor: '#edf2f9' }}>
|
||||||
|
<Row>
|
||||||
|
<Col className='mb-2'>
|
||||||
|
<Card>
|
||||||
|
<CardHeader>
|
||||||
|
<h5>{t('preferences.recording_preferences.title')}</h5>
|
||||||
|
</CardHeader>
|
||||||
|
<CardBody className="bg-light" style={{ minHeight: 300 }}>
|
||||||
|
<small>
|
||||||
|
{t('preferences.recording_preferences.help_text')}
|
||||||
|
</small>
|
||||||
|
|
||||||
|
<Form noValidate className="mt-2 pl-4">
|
||||||
|
<FormGroup>
|
||||||
|
<Input
|
||||||
|
{...register('recording_pref')}
|
||||||
|
checked={selectedPref === 0 || selectedPrefV2 === 0}
|
||||||
|
type='radio'
|
||||||
|
value="0"
|
||||||
|
data-testid="recording_pref_none"
|
||||||
|
onClick={() => setSelectedPref(0)} />
|
||||||
|
<Label for="exampleSelect">{t('preferences.recording_preferences.options.none')}</Label>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
|
<Input
|
||||||
|
{...register('recording_pref')}
|
||||||
|
checked={selectedPref === 1 || selectedPrefV2 === 1}
|
||||||
|
type='radio'
|
||||||
|
value="1"
|
||||||
|
data-testid="recording_pref_my_audio"
|
||||||
|
onClick={() => setSelectedPref(1)} />
|
||||||
|
<Label for="exampleSelect">{t('preferences.recording_preferences.options.my_audio')}</Label>
|
||||||
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
|
<Input
|
||||||
|
{...register('recording_pref')}
|
||||||
|
checked={selectedPref === 2 || selectedPrefV2 === 2}
|
||||||
|
type='radio'
|
||||||
|
value="2"
|
||||||
|
data-testid="recording_pref_my_audio_and_session_mix"
|
||||||
|
onClick={() => setSelectedPref(2)} />
|
||||||
|
<Label for="exampleSelect">{t('preferences.recording_preferences.options.my_audio_and_session_mix')}</Label>
|
||||||
|
</FormGroup>
|
||||||
|
</Form>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
<Col className='d-none d-lg-block'></Col>
|
||||||
|
<Col className='d-none d-lg-block'></Col>
|
||||||
|
</Row>
|
||||||
|
</CardBody>
|
||||||
|
</Card>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default JKAccountPreferences
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
"alerts": {
|
"alerts": {
|
||||||
"updated": "Your account identity has been updated.",
|
"updated": "Your account identity has been updated.",
|
||||||
"confirmation_email_sent": "A confirmation email has been sent to your email address. Please click the link in the email to confirm your email address."
|
"confirmation_email_sent": "A confirmation email has been sent to your email address. Please click the link in the email to confirm your email address."
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"password_form": {
|
"password_form": {
|
||||||
|
|
@ -52,8 +51,20 @@
|
||||||
"help_text_p2": "to reset your password, and you will receive an email with instructions on how to reset your password to the email address associated with your JamKazam account."
|
"help_text_p2": "to reset your password, and you will receive an email with instructions on how to reset your password to the email address associated with your JamKazam account."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"preferences": {
|
||||||
|
"page_title": "Preferences",
|
||||||
|
"recording_preferences": {
|
||||||
|
"title": "Recording",
|
||||||
|
"help_text": "Record the follwing selection on my computer when someone else in a session I'm playing in starts a recording.",
|
||||||
|
"options": {
|
||||||
|
"none": "Don't record anything on my computer",
|
||||||
|
"my_audio": "Record my own audio tracks",
|
||||||
|
"my_audio_and_session_mix": "Record my own audio tracks and the session mix"
|
||||||
|
},
|
||||||
|
"save_success": "Recording preference saved successfully.",
|
||||||
|
"save_error": "Failed to save recording preference. Please try again later."
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"subscription": {
|
"subscription": {
|
||||||
"page_title": "Subscription",
|
"page_title": "Subscription",
|
||||||
|
|
@ -71,7 +82,6 @@
|
||||||
"part1": "To compare the features available for different subscription plans ",
|
"part1": "To compare the features available for different subscription plans ",
|
||||||
"click_here": "click here",
|
"click_here": "click here",
|
||||||
"part2": " to view a help article on our available plans."
|
"part2": " to view a help article on our available plans."
|
||||||
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"play_time": {
|
"play_time": {
|
||||||
|
|
@ -83,7 +93,7 @@
|
||||||
"changed_to_free_plan": "You have chosen to go back down to the FREE PLAN. Your subscription will be canceled, and you will keep your plan until the end of the current billing cycle.",
|
"changed_to_free_plan": "You have chosen to go back down to the FREE PLAN. Your subscription will be canceled, and you will keep your plan until the end of the current billing cycle.",
|
||||||
"failed_to_change_plan": "Failed to update subscription plan. Please try again later. Please contact support@jamkazam.com if you continue to have problems.",
|
"failed_to_change_plan": "Failed to update subscription plan. Please try again later. Please contact support@jamkazam.com if you continue to have problems.",
|
||||||
"changed_plan_successfully": "You have successfully updated your subscription plan."
|
"changed_plan_successfully": "You have successfully updated your subscription plan."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"payments": {
|
"payments": {
|
||||||
"page_title": "Payment History",
|
"page_title": "Payment History",
|
||||||
|
|
@ -98,4 +108,4 @@
|
||||||
"load_more": "Load More",
|
"load_more": "Load More",
|
||||||
"loading": "Loading..."
|
"loading": "Loading..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,6 +59,7 @@ export const accountRoutes = {
|
||||||
{ to: '/account/subscription', name: 'Subscription'},
|
{ to: '/account/subscription', name: 'Subscription'},
|
||||||
{ to: '/account/payments', name: 'Payment History'},
|
{ to: '/account/payments', name: 'Payment History'},
|
||||||
{ to: '/account/payment-method', name: 'Payment Method'},
|
{ to: '/account/payment-method', name: 'Payment Method'},
|
||||||
|
{ to: '/account/preferences', name: 'Preferences'},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
class AddRecordingPrefToUsers < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
execute "ALTER TABLE users ADD COLUMN recording_pref INT"
|
||||||
|
execute "UPDATE users SET recording_pref = 0"
|
||||||
|
end
|
||||||
|
def self.down
|
||||||
|
execute "ALTER TABLE users DROP COLUMN recording_pref"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -66,6 +66,11 @@ module JamRuby
|
||||||
ESCALATION_REASON_OTHER = "Other"
|
ESCALATION_REASON_OTHER = "Other"
|
||||||
ESCALATION_REASONS = [ESCALATION_REASON_NO_AUDIO_STREAM, ESCALATION_REASON_NO_VIDEO_STREAM, ESCALATION_REASON_SETUP_WIZARD_FAILURE, ESCALATION_REASON_OTHER]
|
ESCALATION_REASONS = [ESCALATION_REASON_NO_AUDIO_STREAM, ESCALATION_REASON_NO_VIDEO_STREAM, ESCALATION_REASON_SETUP_WIZARD_FAILURE, ESCALATION_REASON_OTHER]
|
||||||
|
|
||||||
|
enum :recording_pref, [
|
||||||
|
{no_recording: 0},
|
||||||
|
{own_tracks: 1},
|
||||||
|
{own_tracks_and_session_mix: 2}
|
||||||
|
]
|
||||||
|
|
||||||
devise :database_authenticatable, :recoverable, :rememberable
|
devise :database_authenticatable, :recoverable, :rememberable
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ class ApiUsersController < ApiController
|
||||||
photo_url: current_user.photo_url,
|
photo_url: current_user.photo_url,
|
||||||
show_free_jamtrack: current_user.show_free_jamtrack?,
|
show_free_jamtrack: current_user.show_free_jamtrack?,
|
||||||
is_affiliate_partner: current_user.affiliate_partner.present?,
|
is_affiliate_partner: current_user.affiliate_partner.present?,
|
||||||
|
recording_pref: current_user.recording_pref,
|
||||||
}, status: 200
|
}, status: 200
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -246,6 +247,8 @@ class ApiUsersController < ApiController
|
||||||
@user.retailer_interest = !!params[:retailer_interest]
|
@user.retailer_interest = !!params[:retailer_interest]
|
||||||
@user.desired_package = LessonPackageType.find_by_package_type!(params[:desired_package]) if params.has_key?(:desired_package)
|
@user.desired_package = LessonPackageType.find_by_package_type!(params[:desired_package]) if params.has_key?(:desired_package)
|
||||||
@user.accept_desktop_notifications = params[:accept_desktop_notifications] if params.has_key?(:accept_desktop_notifications)
|
@user.accept_desktop_notifications = params[:accept_desktop_notifications] if params.has_key?(:accept_desktop_notifications)
|
||||||
|
@user.recording_pref = params[:recording_pref] if params.has_key?(:recording_pref)
|
||||||
|
|
||||||
if @user.save
|
if @user.save
|
||||||
|
|
||||||
test_drive_package_details = params[:test_drive_package]
|
test_drive_package_details = params[:test_drive_package]
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue