Skip to content

feat: cadre page #180

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/commune-governance/next-env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
/// <reference types="next/image-types/global" />

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information.
// see https://nextjs.org/docs/basic-features/typescript for more information.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const people = [
{
name: 'timo33',
role: '12/08/2024',
},
{
name: '__honza__',
role: '12/08/2024',
},
{
name: 'steinerkelvin',
role: '12/08/2024',
},
{
name: 'jairo.mp4',
role: '12/08/2024',
},
{
name: ' fam7925',
role: '12/08/2024',
}
]

export const CadreMembersList = () => {
return (
<div id="teste" className="grid grid-cols-1 gap-4 sm:grid-cols-4">
{people.map((person) => (
<div
key={person.name}
className="relative flex items-center w-auto space-x-3 border border-white/20 bg-[#898989]/5 px-6 py-5"
>
<div className="w-auto">
<p className="text-sm font-medium text-gray-100">{person.name}</p>
<p className="truncate text-sm text-gray-400">{person.role}</p>
</div>
</div>
))}
</div>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { Loading } from "@commune-ts/ui"
import Image from "next/image";

type Status = "UNVOTED" | "FOR" | "AGAINST" | null

const people = [
{
id: 123,
discordId: "ed.sdr",
requestDate: '12/09/2024',
reason: "Your opinion is fine, it's okay to be wrong! We call it skill issue!",
votesFor: 80,
status: "UNVOTED",
loading: false,

},
{
id: 123,
discordId: "vinicius.sacramento",
requestDate: '12/09/2024',
reason: "What if?",
votesFor: 80,
status: "UNVOTED",
loading: true,
},
{
id: 123,
discordId: "Jack.and.the.huge.beanstalk",
requestDate: '12/09/2024',
reason: "I have some crazy beans on my pocket, would you like to smoke some?",
votesFor: 25,
status: "AGAINST",
loading: false,
},
{
id: 123,
discordId: "lord.pureza",
requestDate: '12/09/2024',
reason: "I'm Pureza. If you keep doing this, I will show you the Squidward Tentacles' nose!",
votesFor: 99,
status: "FOR",
loading: false,
},
]

const handleStatusColors = (status: "FOR" | "AGAINST" | "UNVOTED" | null) => {
const statusColors = {
FOR: "text-green-400 ring-green-400/20",
AGAINST: "text-red-400 ring-red-400/20",
UNVOTED: "text-gray-400 ring-gray-400/20"
}

return statusColors[status ?? "UNVOTED"]
}

function handlePercentages(
favorablePercent: number | null,
): JSX.Element | null {
if (favorablePercent === null) return null;

const againstPercent = 100 - favorablePercent;
if (Number.isNaN(favorablePercent)) {
return (
<div className="w-auto flex pt-2 mt-8 text-center text-sm text-yellow-500 lg:w-auto">
<p>
– %
</p>
</div>
);
}
return (
<div className="flex w-full items-center justify-start space-x-0 divide-x mt-8 divide-white/10 pt-2 text-center text-sm lg:w-auto">
<div className="flex gap-1 pr-2">
<span className="text-green-500">{favorablePercent.toFixed(0)}%</span>
<Image
alt="favorable arrow up icon"
height={14}
src="/favorable-up.svg"
width={10}
/>
</div>
<div className="flex gap-1 pl-2">
<span className="text-red-500"> {againstPercent.toFixed(0)}% </span>
<Image
alt="against arrow down icon"
height={14}
src="/against-down.svg"
width={10}
/>
</div>
</div>
);
}

export const CadreRequestsList = () => {
return (
<ul role="list" className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-2">
{people.map((person) => (
<div className="relative" key={person.id}>
{
person.loading && (
<div className="bg-white/2 absolute z-50 w-full h-full flex justify-center items-center">
<Loading className="h-6 w-6 mr-1" />
<p className="text-gray-300">Approving</p>
</div>
)
}

<li className={`${person.loading ? 'blur-[2px]' : ''} relative col-span-1 divide-y divide-white/20 border border-white/20 bg-[#898989]/5`}>
<div className="flex w-full items-center justify-between space-x-6 p-6">
<div className="flex-1 truncate">
<div className="flex items-center space-x-3">
<h3 className="truncate text-lg font-medium text-gray-100">{person.discordId}</h3>

<span className={`inline-flex flex-shrink-0 items-center rounded-full bg-[#898989]/5 px-1.5 py-0.5 text-xs font-medium ${handleStatusColors(person.status as Status)} ring-1 ring-inset`}>
{person.status}
</span>

</div>
<p className="mt-1 truncate text-sm text-gray-500">{person.requestDate}</p>
<p className='mt-3 text-pretty text-gray-400'>{person.reason}</p>

{handlePercentages(person.votesFor)}

</div>
</div>

<div>
<div className="flex divide-x divide-white/20">
<div className="flex w-0 flex-1">
<a
href={`#`}
className="relative -mr-px inline-flex w-0 flex-1 items-center justify-center gap-x-3 rounded-bl-lg border border-transparent py-4 text-sm font-semibold text-gray-900"
>
<p className='text-red-500'>Refuse</p>

</a>
</div>
<div className="-ml-px flex w-0 flex-1">
<a
href={`#`}
className="relative inline-flex w-0 flex-1 items-center justify-center gap-x-3 rounded-br-lg border border-transparent py-4 text-sm font-semibold text-gray-900"
>
<p className='text-green-500'>Approve</p>
</a>
</div>
</div>
</div>
</li>
</div>
))}
</ul>
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@


export const CadreSectionContainer = ({ children }: { children: React.ReactNode }) => {
return (
<div className="flex w-full flex-col mb-6">
<div className="flex h-full w-full flex-col lg:w-full">
<div className="m-2 flex h-full animate-fade-down flex-col border border-white/20 bg-[#898989]/5 p-6 text-gray-400 backdrop-blur-md animate-delay-100 md:max-h-[60vh] md:min-h-auto">
{children}
</div>
</div>
</div>
)
}
3 changes: 3 additions & 0 deletions apps/commune-governance/src/app/cadre/_components/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export { CadreMembersList } from './cadre-members-list'
export { CadreRequestsList } from './cadre-requests-list'
export { CadreSectionContainer } from './cadre-section-container'
32 changes: 32 additions & 0 deletions apps/commune-governance/src/app/cadre/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Link from "next/link";
import { ArrowLeftIcon } from "@heroicons/react/20/solid";
import { CadreSectionContainer, CadreMembersList, CadreRequestsList } from "./_components";

export default function CadrePage() {
return (
<div className="mx-auto flex max-w-screen-2xl flex-col px-4">
<Link
className="my-6 ml-2 flex w-fit animate-fade-down items-center justify-center gap-2 border border-white/20 bg-[#898989]/5 px-5 py-3 text-gray-400 backdrop-blur-md transition duration-200 hover:border-green-500 hover:bg-green-500/20 hover:text-green-500"
href="/"
>
<ArrowLeftIcon className="h-6 text-green-500" />
Go Back to Proposals List
</Link>

<CadreSectionContainer>
<div className="mb-4 w-full border-b border-gray-500 border-white/20 pb-1 text-gray-400">
<h2 className="text-start text-lg font-semibold text-gray-300">Cadre Requests</h2>
</div>
<CadreRequestsList />
</CadreSectionContainer >

<CadreSectionContainer>
<div className="mb-4 w-full border-b border-gray-500 border-white/20 pb-1 text-gray-400">
<h2 className="text-start text-lg font-semibold text-gray-300">Cadre Members Discord Id's</h2>
</div>
<CadreMembersList />
</CadreSectionContainer>
</div>
)
}

Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ export function BalanceSection({
}): JSX.Element {
const {
isInitialized,
// eslint-disable-next-line @typescript-eslint/unbound-method
handleWalletModal,
daoTreasury,
balance,
Expand Down Expand Up @@ -108,7 +107,7 @@ export function BalanceSection({
<div className="flex animate-fade-down flex-row items-center justify-between border-t !border-white/20 bg-[#898989]/5 p-6 pr-6 animate-delay-200 lg:w-1/3 lg:border lg:pr-10">
<div className="flex flex-col items-start gap-1">
{!isInitialized ||
(selectedAccount?.meta.name && userStakeWeight == null) ? (
(selectedAccount?.meta.name && userStakeWeight == null) ? (
<p className="animate-pulse text-gray-400">
Loading...
<span className="text-lg text-white"> COMAI</span>
Expand Down
1 change: 1 addition & 0 deletions apps/commune-governance/src/app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export default function RootLayout({
navigationLinks={[
{ name: "Homepage", href: links.landing_page, external: true },
{ name: "Join Community", href: links.discord, external: true },
{ name: "Cadre", href: links.cadre, external: false },
]}
/>
{children}
Expand Down
4 changes: 2 additions & 2 deletions packages/providers/src/context/commune.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ interface CommuneContextType {
selectedAccount: InjectedAccountWithMeta | null;
setSelectedAccount: (arg: InjectedAccountWithMeta | null) => void;

handleWalletModal(state?: boolean): void;
handleWalletModal: (state?: boolean) => void;
openWalletModal: boolean;

addStake: (stake: Stake) => Promise<void>;
Expand Down Expand Up @@ -222,7 +222,7 @@ export function CommuneProvider({
}
}

function handleWalletModal(state?: boolean): void {
const handleWalletModal = (state?: boolean): void => {
setOpenWalletModal(state || !openWalletModal);
}

Expand Down
13 changes: 6 additions & 7 deletions packages/types/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import type { ApiDecoration } from "@polkadot/api/types";
import type { Header } from "@polkadot/types/interfaces";
import type { Codec, IU8a } from "@polkadot/types/types";
import type { Enum, Tagged } from "rustie";
import { Variant } from "rustie/dist/enum";
import { z } from "zod";
import type { Variant } from "rustie/dist/enum";
import type { z } from "zod";

import {
import type {
CUSTOM_METADATA_SCHEMA,
DAO_APPLICATIONS_SCHEMA,
DAO_METADATA_SCHEMA,
Expand Down Expand Up @@ -93,11 +93,11 @@ export interface StakeFromData {
perAddr: Map<string, bigint>;
}

export type VoteWithStake = {
export interface VoteWithStake {
address: SS58Address;
stake: bigint;
vote: "In Favor" | "Against";
};
}

export interface LastBlock {
blockHeader: Header;
Expand Down Expand Up @@ -242,8 +242,7 @@ export interface UnrewardedProposal {

// == Field Params ==

export interface SubspaceModule
extends z.infer<typeof SUBSPACE_MODULE_SCHEMA> {}
export type SubspaceModule = z.infer<typeof SUBSPACE_MODULE_SCHEMA>

export type OptionalProperties<T> = keyof T extends infer K
? K extends keyof T
Expand Down
5 changes: 3 additions & 2 deletions packages/ui/src/components/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { cn } from "..";

export function Loading(): JSX.Element {
export function Loading(props: { className?: string }): JSX.Element {
const { className } = props;
return (
<div className={cn("mr-1 grid place-content-center")} role="status">
<svg
aria-hidden="true"
className={cn("h-8 w-8 animate-spin fill-green-500 text-white/20")}
className={cn(`h-8 w-8 animate-spin fill-green-500 text-white/20 ${className}`)}
fill="none"
viewBox="0 0 100 101"
xmlns="http://www.w3.org/2000/svg"
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const links = {
about: "/about",
docs: "/docs/getting-started/intro",
cadre: "/cadre",

blog: "https://mirror.xyz/0xD80E194aBe2d8084fAecCFfd72877e63F5822Fc5",
discord: "https://discord.com/invite/A8JGkZ9Dmm",
Expand Down