Skip to content

Commit

Permalink
Add notification settings in Team and Profile pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Nishant Samel committed Jun 26, 2024
1 parent 1409fcf commit 8138691
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

class InternalApi::V1::TeamMembers::NotificationPreferencesController < InternalApi::V1::ApplicationController
def show
authorize notification_preference, policy_class: TeamMembers::NotificationPreferencePolicy
render json: { notification_enabled: notification_preference.notification_enabled }, status: :ok
end

def update
authorize notification_preference, policy_class: TeamMembers::NotificationPreferencePolicy

notification_preference.update!(notification_preference_params)
render json: {
notification_enabled: notification_preference.notification_enabled,
notice: "Preference updated successfully"
}, status: :ok
end

private

def notification_preference
@notification_preference ||= NotificationPreference.find_by(
user_id: params[:team_id],
company_id: current_company.id)
end

def notification_preference_params
params.require(:notification_preference).permit(:notification_enabled)
end
end
11 changes: 11 additions & 0 deletions app/javascript/src/apis/preferences.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import axios from "./api";

const get = async userId =>
axios.get(`team/${userId}/notification_preferences`);

const updatePreference = async (userId, payload) =>
axios.patch(`team/${userId}/notification_preferences`, payload);

const preferencesApi = { get, updatePreference };

export default preferencesApi;
10 changes: 10 additions & 0 deletions app/javascript/src/components/Profile/Layout/routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import AllocatedDevicesDetails from "components/Profile/Personal/Devices";
import AllocatedDevicesEdit from "components/Profile/Personal/Devices/Edit";
import EmploymentDetails from "components/Profile/Personal/Employment";
import EmploymentDetailsEdit from "components/Profile/Personal/Employment/Edit";
import NotificationPreferences from "components/Profile/Personal/NotificationPreferences";
import UserDetailsView from "components/Profile/Personal/User";
import UserDetailsEdit from "components/Profile/Personal/User/Edit";
import { Roles } from "constants/index";
Expand Down Expand Up @@ -80,6 +81,15 @@ export const SETTINGS = [
category: "personal",
isTab: false,
},
{
label: "NOTIFICATION SETTINGS",
path: "notifications",
icon: <MobileIcon className="mr-2" size={20} weight="bold" />,
authorisedRoles: [ADMIN, OWNER, BOOK_KEEPER, EMPLOYEE],
Component: NotificationPreferences,
category: "personal",
isTab: true,
},
// Uncomment when Integrating with API
// {
// label: "COMPENSATION",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/* eslint-disable no-unused-vars */
import React, { Fragment, useEffect, useState } from "react";

import { useParams } from "react-router-dom";

import preferencesApi from "apis/preferences";
import CustomCheckbox from "common/CustomCheckbox";
import Loader from "common/Loader/index";
import DetailsHeader from "components/Profile/Common/DetailsHeader";
import { useProfileContext } from "context/Profile/ProfileContext";
import { useUserContext } from "context/UserContext";

const NotificationPreferences = () => {
const { user } = useUserContext();
const { memberId } = useParams();
const { isCalledFromSettings } = useProfileContext();
const currentUserId = isCalledFromSettings ? user.id : memberId;

const [isLoading, setIsLoading] = useState<boolean>(false);
const [isSelected, setIsSelected] = useState<boolean>(false);

const getPreferences = async () => {
const res = await preferencesApi.get(currentUserId);
setIsSelected(res.data.notification_enabled);
setIsLoading(false);
};

const updatePreferences = async () => {
setIsLoading(true);
const res = await preferencesApi.updatePreference(currentUserId, {
notification_enabled: !isSelected,
});
setIsSelected(res.data.notification_enabled);
setIsLoading(false);
};

useEffect(() => {
setIsLoading(true);
getPreferences();
}, []);

return (
<Fragment>
<DetailsHeader subTitle="" title="Notification Settings" />
{isLoading ? (
<Loader className="min-h-70v" />
) : (
<CustomCheckbox
isUpdatedDesign
checkboxValue={isSelected}
handleCheck={updatePreferences}
handleOnClick={e => e.stopPropagation()}
id={currentUserId}
isChecked={isSelected}
labelClassName="ml-4"
text="Weekly Email Reminder"
wrapperClassName="py-3 px-5 flex items-center hover:bg-miru-gray-100"
/>
)}
</Fragment>
);
};

export default NotificationPreferences;
26 changes: 26 additions & 0 deletions app/policies/team_members/notification_preference_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# frozen_string_literal: true

class TeamMembers::NotificationPreferencePolicy < ApplicationPolicy
def show?
return false unless record.present?

authorize_current_user
end

def update?
return false unless record.present?

authorize_current_user
end

private

def authorize_current_user
unless user.current_workspace_id == record.company_id
@error_message_key = :different_workspace
return false
end

has_owner_or_admin_role? || record_belongs_to_user?
end
end
1 change: 1 addition & 0 deletions config/routes/internal_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
resource :details, only: [:show, :update], controller: "team_members/details"
resource :avatar, only: [:update, :destroy], controller: "team_members/avatar"
collection { put "update_team_members" }
resource :notification_preferences, only: [:show, :update], controller: "team_members/notification_preferences"
end

resources :invitations, only: [:create, :update, :destroy] do
Expand Down

0 comments on commit 8138691

Please sign in to comment.