-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Proposal Notifications support (#167)
* make vote notification optional * added notification for proposal * update file names * Update Proposals.jsx --------- Co-authored-by: Elliot Braem <16282460+elliotBraem@users.noreply.github.com>
- Loading branch information
1 parent
ad82aa6
commit a04c38c
Showing
10 changed files
with
340 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
const { href } = VM.require("buildhub.near/widget/lib.url") || { | ||
href: () => {} | ||
}; | ||
|
||
if (!props.type) { | ||
return "Loading ..."; | ||
} | ||
|
||
return <>{props.message}</>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const { href } = VM.require("buildhub.near/widget/lib.url") || { | ||
href: () => {} | ||
}; | ||
|
||
if (!props.type) { | ||
return "Loading ..."; | ||
} | ||
|
||
return ( | ||
<a | ||
className="fw-bold text-muted" | ||
href={href({ | ||
widgetSrc: props.widget, | ||
params: { | ||
page: props.page, | ||
proposalId: props.params.proposalId, | ||
tab: props.params.tab, | ||
daoId: props.params.daoId | ||
} | ||
})} | ||
> | ||
View | ||
</a> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
const { value } = props; | ||
|
||
return ( | ||
<Widget | ||
src="mob.near/widget/Notification.Item.LR" | ||
props={{ | ||
L: ( | ||
<Widget | ||
src="buildhub.near/widget/notification.Item.Left" | ||
props={{ ...value }} | ||
/> | ||
), | ||
R: ( | ||
<Widget | ||
src="buildhub.near/widget/notification.Item.Right" | ||
props={{ ...value }} | ||
/> | ||
), | ||
...props | ||
}} | ||
/> | ||
); |
173 changes: 173 additions & 0 deletions
173
apps/builddao/widget/Notification/NotificationRolesSelector.jsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
const DaoSDK = VM.require("sdks.near/widget/SDKs.Sputnik.DaoSDK"); | ||
const { InputField } = VM.require("buildhub.near/widget/components") || { | ||
InputField: <></> | ||
}; | ||
|
||
if (!DaoSDK) { | ||
return <></>; | ||
} | ||
const [groupsAndMembers, setGroupsAndMembers] = useState([]); | ||
const [selectedRoles, setSelectedRoles] = useState({}); // { role:boolean } | ||
const daoId = props.daoId || "build.sputnik-dao.near"; | ||
const accountId = props.accountId ?? context.accountId; | ||
const onUpdate = props.onUpdate ?? (() => {}); | ||
const proposalType = props.proposalType; | ||
const [message, setMessage] = useState( | ||
`${accountId} created ${proposalType} proposal for ${daoId}` | ||
); | ||
const bootstrapTheme = props.bootstrapTheme || "dark"; | ||
|
||
const sdk = DaoSDK(daoId); | ||
|
||
const group = sdk.getGroupsAndMembers(); | ||
if (group === null || !group.length) { | ||
return; | ||
} | ||
setGroupsAndMembers(group); | ||
|
||
const handleCheckboxChange = (role) => { | ||
setSelectedRoles((prevRoles) => { | ||
if (prevRoles.hasOwnProperty(role)) { | ||
return { | ||
...prevRoles, | ||
[role]: !prevRoles[role] | ||
}; | ||
} else { | ||
return { | ||
...prevRoles, | ||
[role]: true | ||
}; | ||
} | ||
}); | ||
}; | ||
|
||
const ThemeContainer = | ||
props.ThemeContainer || | ||
styled.div` | ||
--primary-color: rgb(255, 175, 81); | ||
`; | ||
|
||
const Wrapper = styled.div` | ||
.checked > span:first-child { | ||
background: var(--primary-color) !important; | ||
border-color: var(--primary-color) !important; | ||
} | ||
.cbx:hover span:first-child { | ||
border-color: var(--primary-color) !important; | ||
} | ||
button[type="checkbox"]:hover { | ||
background: none !important; | ||
} | ||
label { | ||
font-size: 13px; | ||
} | ||
`; | ||
|
||
const createNotificationsData = () => { | ||
const someRoleSelected = Object.values(selectedRoles).some( | ||
(value) => value === true | ||
); | ||
if (!someRoleSelected) { | ||
return null; | ||
} | ||
const membersToNotify = []; | ||
Object.keys(selectedRoles).map((item) => { | ||
if (selectedRoles[item] === true) { | ||
membersToNotify = membersToNotify.concat( | ||
groupsAndMembers.find((group) => group.name === item).members | ||
); | ||
} | ||
}); | ||
const uniqueMembersArray = [...new Set(membersToNotify)]; | ||
const notification = { | ||
[accountId]: { | ||
index: { | ||
notify: JSON.stringify( | ||
uniqueMembersArray.map((account) => { | ||
return { | ||
key: account, | ||
value: { | ||
message: message, | ||
params: { | ||
daoId: daoId, | ||
tab: "proposals", | ||
page: "proposal" | ||
}, | ||
type: "buildhub/custom", | ||
widget: "buildhub.near/widget/home" | ||
} | ||
}; | ||
}) | ||
) | ||
} | ||
} | ||
}; | ||
const call = [ | ||
{ | ||
contractName: "social.near", | ||
methodName: "set", | ||
args: { data: notification, options: { refund_unused_deposit: true } }, | ||
deposit: 200000000000000000000000 | ||
} | ||
]; | ||
return call; | ||
}; | ||
|
||
useEffect(() => { | ||
onUpdate(createNotificationsData()); | ||
}, [selectedRoles]); | ||
|
||
const capitalizeFirstLetter = (string) => { | ||
return string.charAt(0).toUpperCase() + string.slice(1); | ||
}; | ||
|
||
const groupList = useMemo(() => { | ||
return ( | ||
Array.isArray(groupsAndMembers) && | ||
groupsAndMembers.map((group) => { | ||
const membersLength = group?.members.length; | ||
if (!membersLength) { | ||
return null; | ||
} | ||
return ( | ||
<div key={group}> | ||
<Widget | ||
src="nearui.near/widget/Input.Checkbox" | ||
props={{ | ||
label: ( | ||
<div> | ||
{capitalizeFirstLetter(group.name)} ({membersLength} members) | ||
</div> | ||
), | ||
onChange: (checked) => handleCheckboxChange(group.name), | ||
checked: selectedRoles[group.name] ?? false | ||
}} | ||
/> | ||
</div> | ||
); | ||
}) | ||
); | ||
}, [groupsAndMembers, selectedRoles]); | ||
|
||
return ( | ||
<ThemeContainer> | ||
<Wrapper className="d-flex flex-column gap-2"> | ||
<div>Send notification to following roles: (Optional)</div> | ||
<div> | ||
<label htmlFor={"notifications-label" + daoId}>Custom Message</label> | ||
<input | ||
name={"notifications-label" + daoId} | ||
id={"notifications-label" + daoId} | ||
className="form-control" | ||
data-bs-theme={bootstrapTheme} | ||
value={message} | ||
onChange={(e) => setMessage(e.target.value)} | ||
/> | ||
</div> | ||
<div>{groupList}</div> | ||
</Wrapper> | ||
</ThemeContainer> | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.