Skip to content

Commit 88d8039

Browse files
authored
[xc-admin] add feature to send proposal to update permissions (#498)
* fix wallet hydration error * update package-lock.json * add edit feature * [wip] sqds proposal * [wip] fix multisig hook * checkpoint * update UI * fix error * refactor * make Modal reusable * address comments
1 parent ad2d1eb commit 88d8039

File tree

16 files changed

+661
-92
lines changed

16 files changed

+661
-92
lines changed

governance/xc-admin/package-lock.json

Lines changed: 50 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const EditButton = ({
2+
editable,
3+
onClick,
4+
}: {
5+
editable?: boolean
6+
onClick: React.MouseEventHandler<HTMLButtonElement>
7+
}) => {
8+
return (
9+
<button
10+
className={`bg-darkGray2 py-3 px-6 text-sm font-semibold uppercase outline-none transition-colors`}
11+
onClick={onClick}
12+
>
13+
<span>{editable ? 'done' : 'edit'}</span>
14+
</button>
15+
)
16+
}
17+
18+
export default EditButton
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { Dialog, Transition } from '@headlessui/react'
2+
import { Dispatch, Fragment, SetStateAction } from 'react'
3+
import CloseIcon from '../icons/CloseIcon'
4+
import Spinner from './Spinner'
5+
6+
const Modal: React.FC<{
7+
isModalOpen: boolean
8+
setIsModalOpen: Dispatch<SetStateAction<boolean>>
9+
closeModal: () => void
10+
changes: any
11+
handleSendProposalButtonClick: () => void
12+
isSendProposalButtonLoading: boolean
13+
}> = ({
14+
isModalOpen,
15+
setIsModalOpen,
16+
closeModal,
17+
changes,
18+
handleSendProposalButtonClick,
19+
isSendProposalButtonLoading,
20+
}) => {
21+
return (
22+
<Transition appear show={isModalOpen} as={Fragment}>
23+
<Dialog
24+
as="div"
25+
className="relative z-10"
26+
onClose={() => setIsModalOpen(false)}
27+
>
28+
<Transition.Child
29+
as={Fragment}
30+
enter="ease-out duration-300"
31+
enterFrom="opacity-0"
32+
enterTo="opacity-100"
33+
leave="ease-in duration-200"
34+
leaveFrom="opacity-100"
35+
leaveTo="opacity-0"
36+
>
37+
<div className="fixed inset-0 bg-black bg-opacity-50" />
38+
</Transition.Child>
39+
<div className="fixed inset-0 overflow-y-auto">
40+
<div className="flex min-h-full items-center justify-center p-4 text-center">
41+
<Transition.Child
42+
as={Fragment}
43+
enter="ease-out duration-300"
44+
enterFrom="opacity-0 scale-95"
45+
enterTo="opacity-100 scale-100"
46+
leave="ease-in duration-200"
47+
leaveFrom="opacity-100 scale-100"
48+
leaveTo="opacity-0 scale-95"
49+
>
50+
<Dialog.Panel className="diaglogPanel">
51+
<button className="diaglogClose" onClick={closeModal}>
52+
<span className="mr-3">close</span> <CloseIcon />
53+
</button>
54+
<div className="max-w-full">
55+
<Dialog.Title as="h3" className="diaglogTitle">
56+
Proposed Changes
57+
</Dialog.Title>
58+
59+
{!changes ? (
60+
<p className="mb-8 leading-6 ">No proposed changes.</p>
61+
) : (
62+
Object.keys(changes).map((key) => {
63+
if (changes[key].prev !== changes[key].new) {
64+
return (
65+
<div
66+
key={key}
67+
className="flex items-center justify-between pb-4"
68+
>
69+
<span className="pr-4 text-left font-bold">
70+
{key}
71+
</span>
72+
<span className="mr-2">
73+
{changes[key].prev} &rarr; {changes[key].new}
74+
</span>
75+
</div>
76+
)
77+
}
78+
})
79+
)}
80+
81+
<button
82+
className="action-btn text-base "
83+
onClick={handleSendProposalButtonClick}
84+
disabled={!changes}
85+
>
86+
{isSendProposalButtonLoading ? (
87+
<Spinner />
88+
) : (
89+
'Send Proposal'
90+
)}
91+
</button>
92+
</div>
93+
</Dialog.Panel>
94+
</Transition.Child>
95+
</div>
96+
</div>
97+
</Dialog>
98+
</Transition>
99+
)
100+
}
101+
102+
export default Modal
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react'
2+
3+
const Spinner = () => {
4+
return (
5+
<svg
6+
className="inline-block h-4 w-4 animate-spin "
7+
xmlns="http://www.w3.org/2000/svg"
8+
fill="none"
9+
viewBox="0 0 24 24"
10+
>
11+
<circle
12+
className="opacity-25"
13+
cx={12}
14+
cy={12}
15+
r={10}
16+
stroke="currentColor"
17+
strokeWidth={3}
18+
/>
19+
<path
20+
className="opacity-75"
21+
fill="currentColor"
22+
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
23+
/>
24+
</svg>
25+
)
26+
}
27+
export default Spinner
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const CloseIcon = () => {
2+
return (
3+
<svg
4+
width={13}
5+
height={13}
6+
viewBox="0 0 13 13"
7+
fill="none"
8+
xmlns="http://www.w3.org/2000/svg"
9+
>
10+
<path
11+
d="M12.1934 0L6.5 5.69343L0.806569 0L0 0.806569L5.69343 6.5L0 12.1934L0.806569 13L6.5 7.30657L12.1934 13L13 12.1934L7.30657 6.5L13 0.806569L12.1934 0Z"
12+
fill="#E6DAFE"
13+
/>
14+
</svg>
15+
)
16+
}
17+
18+
export default CloseIcon

governance/xc-admin/packages/xc-admin-frontend/components/layout/Header.tsx

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,23 @@
1-
import { WalletMultiButton } from '@solana/wallet-adapter-react-ui'
1+
import dynamic from 'next/dynamic'
22
import Link from 'next/link'
33
import { useRouter } from 'next/router'
44
import { useContext, useEffect, useState } from 'react'
55
import { ClusterContext, DEFAULT_CLUSTER } from '../../contexts/ClusterContext'
66
import Pyth from '../../images/logomark.inline.svg'
77
import MobileMenu from './MobileMenu'
88

9+
const WalletMultiButtonDynamic = dynamic(
10+
async () =>
11+
(await import('@solana/wallet-adapter-react-ui')).WalletMultiButton,
12+
{ ssr: false }
13+
)
14+
915
export interface BurgerState {
1016
initial: boolean | null
1117
opened: boolean | null
1218
}
1319

14-
function Header() {
20+
const Header = () => {
1521
const { cluster } = useContext(ClusterContext)
1622
const router = useRouter()
1723
const [isSticky, setIsSticky] = useState(false)
@@ -78,7 +84,7 @@ function Header() {
7884
>
7985
<Link href="/">
8086
<a
81-
className={`flex min-h-[45px] basis-[160px] cursor-pointer items-center`}
87+
className={`flex min-h-[45px] basis-[180px] cursor-pointer items-center`}
8288
>
8389
<Pyth />
8490
</a>
@@ -107,11 +113,17 @@ function Header() {
107113
</ul>
108114
</nav>
109115
<div className="flex items-center justify-end space-x-2">
110-
{headerState.opened ? null : (
111-
<WalletMultiButton className="primary-btn pt-0.5" />
112-
)}
116+
<div className="h-[45px] w-[180px]">
117+
{headerState.opened ? null : (
118+
<WalletMultiButtonDynamic className="primary-btn float-right pt-0.5" />
119+
)}
120+
</div>
113121
<div
114-
className={`relative top-0 right-5 left-0 basis-7
122+
className={`${
123+
headerState.opened
124+
? 'relative top-0 right-5 left-0 basis-7'
125+
: 'lg:hidden'
126+
}
115127
`}
116128
onClick={handleToggleMenu}
117129
>

governance/xc-admin/packages/xc-admin-frontend/components/layout/Layout.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react'
22
import Footer from './Footer'
33
import Header from './Header'
44

5-
export default function Layout({ children }: { children: React.ReactNode }) {
5+
const Layout = ({ children }: { children: React.ReactNode }) => {
66
return (
77
<div className="relative overflow-hidden">
88
<Header />
@@ -11,3 +11,5 @@ export default function Layout({ children }: { children: React.ReactNode }) {
1111
</div>
1212
)
1313
}
14+
15+
export default Layout

governance/xc-admin/packages/xc-admin-frontend/components/tabs/MinPublishers.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ const MinPublishers = () => {
6262
)
6363
) : (
6464
<tr className="border-t border-beige-300">
65-
<td className="py-3 pl-1 lg:pl-14" colSpan={2}>
65+
<td className="py-3 pl-4 lg:pl-14" colSpan={2}>
6666
No mapping accounts found.
6767
</td>
6868
</tr>

0 commit comments

Comments
 (0)