-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Refactor: Update delegateModuleStore and store related components
- Remove the 'title' property from the DelegatedModule interface in delegateModuleStore.ts - Reorder properties in the DelegatedModule interface in delegateModuleStore.ts - Add the 'Module' type to the types.ts file - Add the 'Module' type to the ReportReason type in types.ts - Update the 'name' and 'percentage' properties in the DelegateModuleWeight component - Update the 'name' and 'founderAddress' properties in the DelegateSubnetWeight component - Update the DelegatedSubnet interface in delegateSubnetStore.ts - Update the DelegatedSubnet type in delegateSubnetStore.ts - Update the DelegatedList component to use the new properties in the DelegatedSubnet interface - Update the DelegatedList component to use the new properties in the DelegatedSubnet type
- Loading branch information
Showing
18 changed files
with
554 additions
and
309 deletions.
There are no files selected for viewing
159 changes: 159 additions & 0 deletions
159
apps/commune-validator/src/app/(expanded-pages)/module/[...slug]/page.tsx
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,159 @@ | ||
import Link from "next/link"; | ||
import { notFound } from "next/navigation"; | ||
import { ArrowLeftIcon } from "@heroicons/react/16/solid"; | ||
|
||
import { MarkdownView } from "@commune-ts/ui/markdown-view"; | ||
import { | ||
fetchCustomMetadata, | ||
formatToken, | ||
smallAddress, | ||
} from "@commune-ts/utils"; | ||
|
||
import type { Module } from "~/utils/types"; | ||
import { ReportModule } from "~/app/components/report-module"; | ||
import { api } from "~/trpc/server"; | ||
|
||
interface Params { | ||
params: { | ||
slug: string[]; | ||
}; | ||
} | ||
|
||
interface CustomMetadata { | ||
Ok?: { | ||
title?: string; | ||
body?: string; | ||
}; | ||
} | ||
|
||
export default async function ModulePage({ params }: Params) { | ||
const { slug } = params; | ||
|
||
if (slug.length !== 1) { | ||
notFound(); | ||
} | ||
|
||
const id = slug[0]; | ||
|
||
if (!/^\d+$/.test(String(id))) { | ||
notFound(); | ||
} | ||
|
||
const mdl = await api.module.byId({ id: Number(id) }); | ||
|
||
if (!mdl) { | ||
notFound(); | ||
} | ||
|
||
const metadata = (await fetchCustomMetadata( | ||
"proposal", | ||
mdl.id, | ||
mdl.metadataUri ?? "", | ||
)) as CustomMetadata; | ||
|
||
const title = metadata.Ok?.title ?? "No Metadata"; | ||
// limited to 140 characters | ||
const description = metadata.Ok?.body ?? "This module has no custom metadata"; | ||
|
||
return ( | ||
<div className="container mx-auto p-4 pb-28 text-white"> | ||
<div className="my-16 flex w-full items-center justify-between"> | ||
<Link | ||
href="/" | ||
className="absolute z-10 flex animate-fade-left items-center gap-1 border border-white/20 bg-[#898989]/5 p-2 pr-3 text-white backdrop-blur-md transition duration-200 hover:border-green-500 hover:bg-green-500/10" | ||
> | ||
<ArrowLeftIcon className="h-5 w-5 text-green-500" /> | ||
Go back to modules list | ||
</Link> | ||
<h1 className="flex-grow animate-fade-right text-center text-3xl font-semibold"> | ||
{title} | ||
</h1> | ||
<div className=""> | ||
<ReportModule moduleId={mdl.id} /> | ||
</div> | ||
</div> | ||
<div className="flex flex-col-reverse gap-6 md:flex-row"> | ||
<div className="animate-fade-down animate-delay-300 md:w-[60%] xl:w-[70%]"> | ||
<div className="border border-white/20 bg-[#898989]/5 p-8 backdrop-blur-md"> | ||
<h2 className="mb-4 text-xl font-semibold">Description</h2> | ||
<MarkdownView source={description} /> | ||
</div> | ||
</div> | ||
<div className="flex animate-fade-down flex-col gap-6 animate-delay-500 md:w-[40%] xl:w-[30%]"> | ||
<ModuleDataGrid module={mdl} /> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
function ModuleDataGrid({ module }: { module: Module }) { | ||
const dataGroups = [ | ||
{ | ||
title: "General Information", | ||
fields: [ | ||
{ label: "Module ID", value: module.moduleId }, | ||
{ label: "Netuid", value: module.netuid }, | ||
{ label: "Name", value: module.name ?? "N/A" }, | ||
{ label: "Module Key", value: smallAddress(module.moduleKey) }, | ||
{ label: "At Block", value: module.atBlock }, | ||
{ | ||
label: "Registration Block", | ||
value: module.registrationBlock ?? "N/A", | ||
}, | ||
{ | ||
label: "Registered At", | ||
value: new Date(module.createdAt).toLocaleString(), | ||
}, | ||
], | ||
}, | ||
{ | ||
title: "URIs", | ||
fields: [ | ||
{ label: "Address URI", value: module.addressUri ?? "N/A" }, | ||
{ label: "Metadata URI", value: module.metadataUri ?? "N/A" }, | ||
], | ||
}, | ||
{ | ||
title: "Economic Parameters", | ||
fields: [ | ||
{ label: "Emission", value: formatToken(module.totalStakers ?? 0) }, | ||
{ label: "Incentive", value: formatToken(module.incentive ?? 0) }, | ||
{ label: "Dividend", value: formatToken(module.dividend ?? 0) }, | ||
{ label: "Delegation Fee", value: `${module.delegationFee ?? 0}%` }, | ||
], | ||
}, | ||
{ | ||
title: "Staking Information", | ||
fields: [ | ||
{ label: "Total Staked", value: formatToken(module.totalStaked ?? 0) }, | ||
{ label: "Total Stakers", value: module.totalStakers ?? 0 }, | ||
{ | ||
label: "Total Rewards", | ||
value: formatToken(module.totalRewards ?? 0), | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
return ( | ||
<div className="grid gap-6"> | ||
{dataGroups.map((group, index) => ( | ||
<div | ||
key={index} | ||
className="border border-white/20 bg-[#898989]/5 p-6 backdrop-blur-md" | ||
> | ||
<h3 className="mb-4 text-lg font-semibold">{group.title}</h3> | ||
<div className="grid gap-2"> | ||
{group.fields.map((field, fieldIndex) => ( | ||
<div key={fieldIndex} className="flex justify-between"> | ||
<span className="text-white/70">{field.label}:</span> | ||
<span className="font-mono">{field.value}</span> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
); | ||
} |
202 changes: 202 additions & 0 deletions
202
apps/commune-validator/src/app/(expanded-pages)/subnet/[...slug]/page.tsx
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,202 @@ | ||
import Link from "next/link"; | ||
import { notFound } from "next/navigation"; | ||
import { ArrowLeftIcon } from "@heroicons/react/16/solid"; | ||
|
||
import { MarkdownView } from "@commune-ts/ui/markdown-view"; | ||
import { fetchCustomMetadata, smallAddress } from "@commune-ts/utils"; | ||
|
||
import type { Subnet } from "~/utils/types"; | ||
// import { ReportSubnet } from "~/app/components/report-Subnet"; | ||
import { api } from "~/trpc/server"; | ||
|
||
interface Params { | ||
params: { | ||
slug: string[]; | ||
}; | ||
} | ||
|
||
interface CustomMetadata { | ||
Ok?: { | ||
title?: string; | ||
body?: string; | ||
}; | ||
} | ||
|
||
export default async function SubnetPage({ params }: Params) { | ||
const { slug } = params; | ||
|
||
if (slug.length !== 1) { | ||
notFound(); | ||
} | ||
|
||
const id = slug[0]; | ||
|
||
if (!/^\d+$/.test(String(id))) { | ||
notFound(); | ||
} | ||
|
||
const sbnt = await api.subnet.byId({ id: Number(id) }); | ||
|
||
if (!sbnt) { | ||
notFound(); | ||
} | ||
|
||
const metadata = (await fetchCustomMetadata( | ||
"proposal", | ||
sbnt.id, | ||
sbnt.subnetMetadata ?? "", | ||
)) as CustomMetadata; | ||
|
||
const title = metadata.Ok?.title ?? "No Metadata"; | ||
|
||
const description = metadata.Ok?.body ?? "This Subnet has no custom metadata"; | ||
|
||
return ( | ||
<div className="container mx-auto p-4 pb-28 text-white"> | ||
<div className="my-16 flex w-full items-center justify-between"> | ||
<Link | ||
href="/" | ||
className="absolute z-10 flex animate-fade-left items-center gap-1 border border-white/20 bg-[#898989]/5 p-2 pr-3 text-white backdrop-blur-md transition duration-200 hover:border-green-500 hover:bg-green-500/10" | ||
> | ||
<ArrowLeftIcon className="h-5 w-5 text-green-500" /> | ||
Go back to Subnets list | ||
</Link> | ||
<h1 className="flex-grow animate-fade-right text-center text-3xl font-semibold"> | ||
{title} | ||
</h1> | ||
</div> | ||
<div className="flex flex-col-reverse gap-6 md:flex-row"> | ||
<div className="animate-fade-down animate-delay-300 md:w-[60%] xl:w-[70%]"> | ||
<div className="border border-white/20 bg-[#898989]/5 p-8 backdrop-blur-md"> | ||
<h2 className="mb-4 text-xl font-semibold">Description</h2> | ||
<MarkdownView source={description} /> | ||
</div> | ||
</div> | ||
<div className="flex animate-fade-down flex-col gap-6 animate-delay-500 md:w-[40%] xl:w-[30%]"> | ||
<SubnetDataGrid subnet={sbnt} /> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
} | ||
|
||
function SubnetDataGrid({ subnet }: { subnet: Subnet }) { | ||
const dataGroups = [ | ||
{ | ||
title: "General Information", | ||
fields: [ | ||
{ label: "Subnet ID", value: subnet.id }, | ||
{ label: "Netuid", value: subnet.netuid }, | ||
{ label: "Name", value: subnet.name }, | ||
{ label: "At Block", value: subnet.atBlock }, | ||
{ label: "Tempo", value: subnet.tempo }, | ||
{ label: "Founder", value: smallAddress(subnet.founder) }, | ||
], | ||
}, | ||
{ | ||
title: "Weight Configuration", | ||
fields: [ | ||
{ label: "Min Allowed Weights", value: subnet.minAllowedWeights }, | ||
{ label: "Max Allowed Weights", value: subnet.maxAllowedWeights }, | ||
{ label: "Max Allowed UIDs", value: subnet.maxAllowedUids }, | ||
{ label: "Max Weight Age", value: subnet.maxWeightAge }, | ||
{ label: "Trust Ratio", value: subnet.trustRatio }, | ||
{ | ||
label: "Max Set Weight Calls/Epoch", | ||
value: subnet.maximumSetWeightCallsPerEpoch, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: "Economic Parameters", | ||
fields: [ | ||
{ label: "Founder Share", value: subnet.founderShare }, | ||
{ label: "Incentive Ratio", value: subnet.incentiveRatio }, | ||
{ label: "Subnet Emission", value: subnet.subnetEmission.toString() }, | ||
{ label: "Bonds MA", value: subnet.bondsMa }, | ||
{ label: "Immunity Period", value: subnet.immunityPeriod }, | ||
], | ||
}, | ||
{ | ||
title: "Governance Configuration", | ||
fields: [ | ||
{ label: "Proposal Cost", value: subnet.proposalCost.toString() }, | ||
{ label: "Proposal Expiration", value: subnet.proposalExpiration }, | ||
{ label: "Vote Mode", value: subnet.voteMode }, | ||
{ | ||
label: "Proposal Reward Treasury Allocation", | ||
value: subnet.proposalRewardTreasuryAllocation, | ||
}, | ||
{ | ||
label: "Max Proposal Reward Treasury Allocation", | ||
value: subnet.maxProposalRewardTreasuryAllocation.toString(), | ||
}, | ||
{ | ||
label: "Proposal Reward Interval", | ||
value: subnet.proposalRewardInterval, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: "Burn Configuration", | ||
fields: [ | ||
{ label: "Min Burn", value: subnet.minBurn.toString() }, | ||
{ label: "Max Burn", value: subnet.maxBurn.toString() }, | ||
{ label: "Adjustment Alpha", value: subnet.adjustmentAlpha }, | ||
{ | ||
label: "Target Registrations Interval", | ||
value: subnet.targetRegistrationsInterval, | ||
}, | ||
{ | ||
label: "Target Registrations Per Interval", | ||
value: subnet.targetRegistrationsPerInterval, | ||
}, | ||
{ | ||
label: "Max Registrations Per Interval", | ||
value: subnet.maxRegistrationsPerInterval, | ||
}, | ||
], | ||
}, | ||
{ | ||
title: "Additional Information", | ||
fields: [ | ||
{ | ||
label: "Min Validator Stake", | ||
value: subnet.minValidatorStake?.toString(), | ||
}, | ||
{ label: "Max Allowed Validators", value: subnet.maxAllowedValidators }, | ||
{ | ||
label: "Created At", | ||
value: new Date(subnet.createdAt).toLocaleString(), | ||
}, | ||
{ | ||
label: "Deleted At", | ||
value: subnet.deletedAt | ||
? new Date(subnet.deletedAt).toLocaleString() | ||
: "N/A", | ||
}, | ||
], | ||
}, | ||
]; | ||
|
||
return ( | ||
<div className="grid gap-6"> | ||
{dataGroups.map((group, index) => ( | ||
<div | ||
key={index} | ||
className="border border-white/20 bg-[#898989]/5 p-6 backdrop-blur-md" | ||
> | ||
<h3 className="mb-4 text-lg font-semibold">{group.title}</h3> | ||
<div className="grid gap-2"> | ||
{group.fields.map((field, fieldIndex) => ( | ||
<div key={fieldIndex} className="flex justify-between"> | ||
<span className="text-white/70">{field.label}:</span> | ||
<span className="font-mono">{field.value ?? "N/A"}</span> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
))} | ||
</div> | ||
); | ||
} |
File renamed without changes.
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
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.