account preferences page

new page to change user's recording preferences
This commit is contained in:
Nuwan 2025-02-03 12:25:21 +05:30
parent 3677181e09
commit 5ff152233b
8 changed files with 176 additions and 6 deletions

View File

@ -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.');
});
});

View File

@ -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} />

View File

@ -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

View File

@ -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": {

View File

@ -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'},
] ]
} }

View File

@ -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

View File

@ -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

View File

@ -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]