GETTING STARTED
- What is SuprSend?
- Quick Start Guide
- Best Practices
- Plan Your Integration
- Go-live checklist
- Security
CORE CONCEPTS
- Templates
- Users
- Events
- Workflow
- Notification Category
- Preferences
- Tenants
- Lists
- Broadcast
- Objects
- DLT Guidelines
- Whatsapp Template Guidelines
WORKFLOW BUILDER
- Design Workflow
- Node List
- Workflow Settings
- Trigger Workflow
- Tenant Workflows
SUPRSEND BACKEND SDK
- Python SDK
- Node.js SDK
- Java SDK
- Go SDK
SUPRSEND CLIENT SDK
- Authentication
- Javascript SDK
- Android
- iOS
- React Native
- Flutter
- React
Notification Inbox
- Overview
- HMAC Authentication
- Multi Tabs
- React
- Javascript (Angular, Vuejs etc)
- React Native (Headless)
- Flutter (Headless)
PREFERENCE CENTRE
VENDOR INTEGRATION GUIDE
- Overview
- Email Integrations
- SMS Integrations
- Android Push
- Whatsapp Integrations
- iOS Push
- Chat Integrations
- Vendor Fallback
- Tenant Vendor
INTEGRATIONS
- Webhook
- Connectors
MONITORING & DEBUGGING
- Logs
- Error Guides
MANAGE YOUR ACCOUNT
React
Preferences
This will guide you through integration steps of preferences in react application
Integration Steps
1
Integrate SuprSendProvider
Integrate SuprSendProvider as it is needed for creating SuprSend Client and authenticating user.
2
Accessing preferences methods using useSuprSendClient hook
Call useSuprSendClient hook in your react component code to get SuprSend client instance which has all preferences methods.
3
Integrating Preferences
Please refer these sections to understand and implement preferences methods in your react application, as integration steps are same for both the web-sdk and react-sdk.
Example
import { useState, useEffect } from "react";
import Switch from "react-switch";
import {
SuprSendProvider,
ChannelLevelPreferenceOptions,
PreferenceOptions,
useSuprSendClient,
useAuthenticateUser,
} from "@suprsend/react";
// -------------- Category Level Preferences -------------- //
const handleCategoryPreferenceChange = async ({
data,
subcategory,
setPreferenceData,
suprSendClient,
}) => {
const resp = await suprSendClient.user.preferences.updateCategoryPreference(
subcategory.category,
data ? PreferenceOptions.OPT_IN : PreferenceOptions.OPT_OUT
);
if (resp.status === "error") {
console.log(resp.error.message);
} else {
setPreferenceData({ ...resp.body });
}
};
const handleChannelPreferenceInCategoryChange = async ({
channel,
subcategory,
setPreferenceData,
suprSendClient,
}) => {
if (!channel.is_editable) return;
const resp =
await suprSendClient.user.preferences.updateChannelPreferenceInCategory(
channel.channel,
channel.preference === PreferenceOptions.OPT_IN
? PreferenceOptions.OPT_OUT
: PreferenceOptions.OPT_IN,
subcategory.category
);
if (resp.status === "error") {
console.log(resp.error.message);
} else {
setPreferenceData({ ...resp.body });
}
};
function NotificationCategoryPreferences({
preferenceData,
setPreferenceData,
}) {
const suprSendClient = useSuprSendClient();
if (!preferenceData.sections) {
return null;
}
return preferenceData.sections?.map((section, index) => {
return (
<div style={{ marginBottom: 24 }} key={index}>
{section?.name && (
<div
style={{
backgroundColor: "#FAFBFB",
paddingTop: 12,
paddingBottom: 12,
marginBottom: 18,
}}
>
<p
style={{
fontSize: 18,
fontWeight: 500,
color: "#3D3D3D",
}}
>
{section.name}
</p>
<p style={{ color: "#6C727F" }}>{section.description}</p>
</div>
)}
{section?.subcategories?.map((subcategory, index) => {
return (
<div
key={index}
style={{
borderBottom: "1px solid #D9D9D9",
paddingBottom: 12,
marginTop: 18,
}}
>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
}}
>
<div>
<p
style={{
fontSize: 16,
fontWeight: 600,
color: "#3D3D3D",
}}
>
{subcategory.name}
</p>
<p style={{ color: "#6C727F", fontSize: 14 }}>
{subcategory.description}
</p>
</div>
<Switch
disabled={!subcategory.is_editable}
onChange={(data) => {
handleCategoryPreferenceChange({
data,
subcategory,
setPreferenceData,
suprSendClient,
});
}}
uncheckedIcon={false}
checkedIcon={false}
height={20}
width={40}
onColor="#2563EB"
checked={subcategory.preference === PreferenceOptions.OPT_IN}
/>
</div>
<div style={{ display: "flex", gap: 10, marginTop: 12 }}>
{subcategory?.channels.map((channel, index) => {
return (
<Checkbox
key={index}
value={channel.preference}
title={channel.channel}
disabled={!channel.is_editable}
onClick={() => {
handleChannelPreferenceInCategoryChange({
channel,
subcategory,
setPreferenceData,
suprSendClient,
});
}}
/>
);
})}
</div>
</div>
);
})}
</div>
);
});
}
// -------------- Channel Level Preferences -------------- //
const handleOverallChannelPreferenceChange = async ({
channel,
status,
setPreferenceData,
suprSendClient,
}) => {
const resp =
await suprSendClient.user.preferences.updateOverallChannelPreference(
channel.channel,
status
);
if (resp.status === "error") {
console.log(resp.error.message);
} else {
setPreferenceData({ ...resp.body });
}
};
function ChannelLevelPreferernceItem({ channel, setPreferenceData }) {
const suprSendClient = useSuprSendClient();
const [isActive, setIsActive] = useState(false);
return (
<div
style={{
border: "1px solid #D9D9D9",
borderRadius: 5,
padding: "12px 24px",
marginBottom: 24,
}}
>
<div
style={{
cursor: "pointer",
}}
onClick={() => setIsActive(!isActive)}
>
<p
style={{
fontSize: 18,
fontWeight: 500,
color: "#3D3D3D",
}}
>
{channel.channel}
</p>
<p style={{ color: "#6C727F", fontSize: 14 }}>
{channel.is_restricted
? "Allow required notifications only"
: "Allow all notifications"}
</p>
</div>
{isActive && (
<div style={{ marginTop: 12, marginLeft: 24 }}>
<p
style={{
color: "#3D3D3D",
fontSize: 16,
fontWeight: 500,
marginTop: 12,
borderBottom: "1px solid #E8E8E8",
}}
>
{channel.channel} Preferences
</p>
<div style={{ marginTop: 12 }}>
<div style={{ marginBottom: 8 }}>
<div
style={{
display: "flex",
alignItems: "center",
}}
>
<div>
<input
type="radio"
name={`all- ${channel.channel}`}
value={true}
id={`all- ${channel.channel}`}
checked={!channel.is_restricted}
onChange={() => {
handleOverallChannelPreferenceChange({
channel,
status: ChannelLevelPreferenceOptions.ALL,
setPreferenceData,
suprSendClient,
});
}}
/>
</div>
<label
htmlFor={`all- ${channel.channel}`}
style={{ marginLeft: 12 }}
>
All
</label>
</div>
<p style={{ color: "#6C727F", fontSize: 14, marginLeft: 22 }}>
Allow All Notifications, except the ones that I have turned off
</p>
</div>
<div>
<div style={{ display: "flex", alignItems: "center" }}>
<div>
<input
type="radio"
name={`required- ${channel.channel}`}
value={true}
id={`required- ${channel.channel}`}
checked={channel.is_restricted}
onChange={() => {
handleOverallChannelPreferenceChange({
channel,
status: ChannelLevelPreferenceOptions.REQUIRED,
setPreferenceData,
suprSendClient,
});
}}
/>
</div>
<label
htmlFor={`required- ${channel.channel}`}
style={{ marginLeft: 12 }}
>
Required
</label>
</div>
<p style={{ color: "#6C727F", fontSize: 14, marginLeft: 22 }}>
Allow only important notifications related to account and
security settings
</p>
</div>
</div>
</div>
)}
</div>
);
}
function ChannelLevelPreferences({ preferenceData, setPreferenceData }) {
return (
<div>
<div
style={{
backgroundColor: "#FAFBFB",
paddingTop: 12,
paddingBottom: 12,
marginBottom: 18,
}}
>
<p
style={{
fontSize: 18,
fontWeight: 500,
color: "#3D3D3D",
}}
>
What notifications to allow for channel?
</p>
</div>
<div>
{preferenceData.channel_preferences ? (
<div>
{preferenceData.channel_preferences?.map((channel, index) => {
return (
<ChannelLevelPreferernceItem
key={index}
channel={channel}
setPreferenceData={setPreferenceData}
/>
);
})}
</div>
) : (
<p>No Data</p>
)}
</div>
</div>
);
}
// -------------- Main component -------------- //
export default function App() {
return (
<SuprSendProvider
publicApiKey="YOUR_PUBLIC_API_KEY"
distinctId={"YOUR_DISTINCT_ID"}
>
<Preferences />
</SuprSendProvider>
);
}
function Preferences() {
const suprSendClient = useSuprSendClient();
const { authenticatedUser } = useAuthenticateUser();
const [preferenceData, setPreferenceData] = useState();
useEffect(() => {
if (!authenticatedUser) return;
suprSendClient.user.preferences.getPreferences().then((resp) => {
if (resp.status === "error") {
console.log(resp.error.message);
} else {
setPreferenceData({ ...resp.body });
}
});
// listen for update in preferences data
suprSendClient.emitter.on("preferences_updated", (preferenceData) => {
setPreferenceData({ ...preferenceData.body });
});
// listen for errors
suprSendClient.emitter.on("preferences_error", (response) => {
console.log("ERROR:", response?.error?.message);
});
}, [authenticatedUser]);
if (!preferenceData) return <p>Loading...</p>;
return (
<div style={{ margin: 24 }}>
<h3 style={{ marginBottom: 24 }}>Notification Preferences</h3>
<NotificationCategoryPreferences
preferenceData={preferenceData}
setPreferenceData={setPreferenceData}
/>
<ChannelLevelPreferences
preferenceData={preferenceData}
setPreferenceData={setPreferenceData}
/>
</div>
);
}
// -------------- Custom Checkbox Component -------------- //
function Checkbox({ title, value, onClick, disabled }) {
const selected = value === PreferenceOptions.OPT_IN;
return (
<div
style={{
border: "0.5px solid #B5B5B5",
display: "inline-flex",
padding: "0px 20px 0px 4px",
borderRadius: 30,
cursor: disabled ? "not-allowed" : "pointer",
}}
onClick={onClick}
>
<Circle selected={selected} disabled={disabled} />
<p
style={{
marginLeft: 8,
color: "#6C727F",
marginTop: 1,
fontWeight: 500,
paddingBottom: 4,
}}
>
{title}
</p>
</div>
);
}
function Circle({ selected, disabled }) {
const bgColor = selected
? disabled
? "#BDCFF8"
: "#2463EB"
: disabled
? "#D0CFCF"
: "#FFF";
return (
<div
style={{
height: 20,
width: 20,
borderRadius: 100,
border: "0.5px solid #A09F9F",
backgroundColor: bgColor,
marginTop: 3.6,
}}
/>
);
}
On this page