-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #75 from Cardano-Forge/feat/MET-47-project-summary
Export + Summary UI
- Loading branch information
Showing
20 changed files
with
472 additions
and
100 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
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
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
52 changes: 52 additions & 0 deletions
52
client/src/app/(validator)/summary/components/data-validation.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,52 @@ | ||
import type { ProjectCollection } from "~/lib/types"; | ||
import { useActiveProject } from "~/providers/active-project.provider"; | ||
|
||
import { StepComponent, StepHeader } from "./step-components"; | ||
import Stat from "~/components/stat"; | ||
import MessageBox from "~/components/message-box"; | ||
import ValidatorStats from "./validator-stats"; | ||
|
||
export default function DataValidation() { | ||
const activeProject = useActiveProject(); | ||
const project = activeProject?.toJSON() as ProjectCollection; | ||
|
||
const hasError = !!project.errorsDetected; | ||
const hasWarning = !!project.errorsFlagged; | ||
const status = hasError ? "error" : hasWarning ? "warning" : "success"; | ||
|
||
return ( | ||
<StepComponent> | ||
<StepHeader title="NFTs data validation" step={3} status={status} /> | ||
<div className="flex flex-row gap-10 p-4"> | ||
<Stat icon="database" stat={project.nfts}> | ||
NFTs in this collection | ||
</Stat> | ||
<Stat icon="clock" stat={project.unchecked}> | ||
NFTs unchecked | ||
</Stat> | ||
<Stat icon="exclamation" stat={project.errorsDetected} variant="error"> | ||
Errors detected | ||
</Stat> | ||
<Stat icon="flag" stat={project.errorsFlagged} variant="warning"> | ||
Errors flagged | ||
</Stat> | ||
<Stat icon="check" stat={project.valids} variant="success"> | ||
Marked as valid | ||
</Stat> | ||
</div> | ||
{hasError && ( | ||
<MessageBox variant="error"> | ||
We still detect some errors in this step. Make sure you correct them | ||
before exporting your project. | ||
</MessageBox> | ||
)} | ||
{hasWarning && ( | ||
<MessageBox> | ||
We still see some flagged errors in this step. Make sure you check | ||
them before exporting your project. | ||
</MessageBox> | ||
)} | ||
<ValidatorStats /> | ||
</StepComponent> | ||
); | ||
} |
73 changes: 73 additions & 0 deletions
73
client/src/app/(validator)/summary/components/metadata-structure.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,73 @@ | ||
import React from "react"; | ||
import { JsonEditor } from "json-edit-react"; | ||
|
||
import { StepComponent, StepHeader } from "./step-components"; | ||
import type { MetadataSchemaCollection, MetadataCollection } from "~/lib/types"; | ||
import { useRxData } from "rxdb-hooks"; | ||
import LoaderComponent from "~/components/loader-component"; | ||
import { getAttributesDistributions } from "~/lib/get/get-attributes-distributions"; | ||
import { | ||
Accordion, | ||
AccordionContent, | ||
AccordionItem, | ||
AccordionTrigger, | ||
} from "~/components/ui/accordion"; | ||
import { jerTheme } from "~/lib/json-editor"; | ||
import ValuesIcon from "~/icons/values.icon"; | ||
|
||
export default function MetadataStructure() { | ||
const { result, isFetching } = useRxData<MetadataCollection>( | ||
"metadata", | ||
(collection) => collection.find(), | ||
); | ||
|
||
const { result: schemaResult, isFetching: isFetchingSchema } = | ||
useRxData<MetadataSchemaCollection>("metadataSchema", (collection) => | ||
collection.find(), | ||
); | ||
|
||
if (isFetching || isFetchingSchema) return <LoaderComponent />; | ||
|
||
const metadatas: MetadataCollection[] = result.map( | ||
(doc) => doc.toJSON() as MetadataCollection, | ||
); | ||
|
||
const schema: MetadataSchemaCollection | undefined = schemaResult.map( | ||
(doc) => doc.toJSON() as MetadataSchemaCollection, | ||
)[0]; | ||
|
||
if (!schema || !metadatas) return <div>No data found.</div>; | ||
|
||
const distribution = getAttributesDistributions(metadatas, schema); | ||
|
||
return ( | ||
<StepComponent> | ||
<StepHeader title="Metadata strucutre" /> | ||
<Accordion type="single" collapsible> | ||
<AccordionItem value="distribution"> | ||
<AccordionTrigger className="hover:no-underline"> | ||
<div className="ml-2 flex flex-row items-center gap-4 text-white/60"> | ||
<div className="items-center justify-center rounded-full border border-white/60 p-2"> | ||
<ValuesIcon className="h-4 w-4" /> | ||
</div> | ||
{`Value's distribution`} | ||
</div> | ||
</AccordionTrigger> | ||
<AccordionContent className="rounded-xl bg-card p-1"> | ||
<JsonEditor | ||
data={distribution} | ||
theme={jerTheme} | ||
rootFontSize={18} | ||
minWidth={"100%"} | ||
collapse={1} | ||
enableClipboard={false} // Disabled copy to clipboard | ||
restrictEdit={() => true} // Disabled edit | ||
restrictAdd={() => true} // Disabled add | ||
restrictDelete={() => true} // Disabled delete | ||
/> | ||
</AccordionContent> | ||
</AccordionItem> | ||
</Accordion> | ||
</StepComponent> | ||
); | ||
} |
61 changes: 61 additions & 0 deletions
61
client/src/app/(validator)/summary/components/rules-selection.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,61 @@ | ||
import React from "react"; | ||
import { StepComponent, StepHeader } from "./step-components"; | ||
import { Typography } from "~/components/typography"; | ||
import { useRxData } from "rxdb-hooks"; | ||
import { type RulesCollection } from "~/lib/types"; | ||
import { useActiveProject } from "~/providers/active-project.provider"; | ||
import LoaderComponent from "~/components/loader-component"; | ||
import { hyphenToTitleCase } from "~/lib/hyphen-to-title-case"; | ||
import { | ||
Accordion, | ||
AccordionContent, | ||
AccordionItem, | ||
AccordionTrigger, | ||
} from "~/components/ui/accordion"; | ||
import { chunk } from "~/lib/chunk"; | ||
import CodeIcon from "~/icons/code.icon"; | ||
|
||
export default function RulesSelection() { | ||
const activeProject = useActiveProject(); | ||
const { result, isFetching } = useRxData<RulesCollection>( | ||
"rules", | ||
(collection) => collection.findByIds([activeProject?.id ?? ""]), | ||
); | ||
|
||
if (isFetching) return <LoaderComponent />; | ||
|
||
const rules: RulesCollection | undefined = result.map( | ||
(doc) => doc.toJSON() as RulesCollection, | ||
)[0]; | ||
|
||
if (!rules) return null; | ||
|
||
return ( | ||
<StepComponent> | ||
<StepHeader title="Rules selection" step={2} /> | ||
<Accordion type="single" collapsible> | ||
<AccordionItem value="rules"> | ||
<AccordionTrigger className="hover:no-underline"> | ||
<div className="ml-2 flex flex-row items-center gap-4 text-white/60"> | ||
<div className="items-center justify-center rounded-full border border-white/60 p-2"> | ||
<CodeIcon className="h-4 w-4" /> | ||
</div> | ||
{`${rules.rules.length} Rule(s) selected for validation`} | ||
</div> | ||
</AccordionTrigger> | ||
<AccordionContent className="flex flex-row gap-10 rounded-xl bg-card p-4"> | ||
{chunk(rules.rules, 4).map((rules, i) => ( | ||
<ul key={`${i}`}> | ||
{rules.map((rule) => ( | ||
<li key={rule}> | ||
<Typography>• {hyphenToTitleCase(rule)}</Typography> | ||
</li> | ||
))} | ||
</ul> | ||
))} | ||
</AccordionContent> | ||
</AccordionItem> | ||
</Accordion> | ||
</StepComponent> | ||
); | ||
} |
72 changes: 72 additions & 0 deletions
72
client/src/app/(validator)/summary/components/step-components.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,72 @@ | ||
import { Typography } from "~/components/typography"; | ||
import CheckCircleIcon from "~/icons/check-circle.icon"; | ||
import ExclamationIcon from "~/icons/exclamation.icon"; | ||
import InformationCircle from "~/icons/information-circle"; | ||
import SummaryIcon from "~/icons/summary.icon"; | ||
import { type Status } from "~/lib/types"; | ||
import { cn } from "~/lib/utils"; | ||
|
||
export function StepComponent({ children }: { children: React.ReactNode }) { | ||
return ( | ||
<div className="flex flex-col gap-4 rounded-xl bg-background p-4"> | ||
{children} | ||
</div> | ||
); | ||
} | ||
|
||
export function StepHeader({ | ||
step = 1, | ||
title, | ||
status = "success", | ||
}: { | ||
step?: number; | ||
title: string; | ||
status?: Status; | ||
}) { | ||
return ( | ||
<> | ||
<div className="flex flex-row items-center justify-between px-2"> | ||
<div className="flex flex-col"> | ||
<Typography className="text-white/50">{`Step ${step}`}</Typography> | ||
<Typography as="h3">{title}</Typography> | ||
</div> | ||
<StepStatus status={status} /> | ||
</div> | ||
<hr className="border-white/20" /> | ||
</> | ||
); | ||
} | ||
|
||
const statusClassName: Record<Status, string> = { | ||
success: "text-success", | ||
warning: "text-warning", | ||
error: "text-destructive", | ||
unchecked: "text-white/50", | ||
}; | ||
|
||
const icons: Record<Status, React.ReactNode> = { | ||
success: <CheckCircleIcon className="h-8 w-8" />, | ||
warning: <InformationCircle className="h-8 w-8" />, | ||
error: <ExclamationIcon className="h-8 w-8" />, | ||
unchecked: <SummaryIcon className="h-8 w-8" />, | ||
}; | ||
|
||
const text: Record<Status, string> = { | ||
success: "Validated", | ||
warning: "Recommandation", | ||
error: "Error detected", | ||
unchecked: "Unchecked", | ||
}; | ||
|
||
export function StepStatus({ status }: { status: Status }) { | ||
return ( | ||
<Typography | ||
className={cn( | ||
"flex flex-row items-center gap-4 tracking-wide", | ||
statusClassName[status], | ||
)} | ||
> | ||
{text[status]} {icons[status]} | ||
</Typography> | ||
); | ||
} |
Oops, something went wrong.