Skip to content
This repository was archived by the owner on Feb 11, 2023. It is now read-only.

Commit 83d6001

Browse files
committed
feat(react): Added a reusable HypercertImage React component
* Adds Plasmic codegen to the project, with instructions in README * Checking in the current Plasmic-generated Hypercert Image * Wrapper component will translate HypercertMetadata to the Plasmic component API
1 parent a39bb8c commit 83d6001

22 files changed

+3907
-45
lines changed

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,25 @@ yarn build
2929
[API documentation](/docs/API.md)
3030
[Graph playground](https://thegraph.com/hosted-service/subgraph/bitbeckers/hypercerts-dev)
3131

32+
## Updating Plasmic designs
33+
34+
The visual designs are edited in [Plasmic](https://plasmic.app?ref=ryscheng). You can sign up for an account [here](https://plasmic.app?ref=ryscheng).
35+
36+
These are then manually synced into React components. You can find a list of all Plasmic-generated React components in `plasmic.json`.
37+
38+
To update the design:
39+
40+
1. Navigate to the [Plasmic project](https://studio.plasmic.app/projects/tKtnZiEMup1PmF99tS3Jhx/). Make sure you have edit permissions.
41+
42+
2. Sync the designs into the repository via `yarn plasmic:sync`.
43+
44+
3. If you are updating the design-code API, make sure to edit the respective wrapper file in `./src/components` (e.g. `HypercertImage.tsx`).
45+
46+
For docs on how to use Plasmic, see the [docs](https://docs.plasmic.app/learn/plasmic-studio-guide/).
47+
Note: this is a different usage pattern than what we do in Next.js codebases.
48+
https://github.com/vercel/next.js/issues/19936
49+
50+
3251
## Packages
3352

3453
### Contracts

package.json

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@network-goods/hypercerts-sdk",
3-
"version": "0.0.12",
3+
"version": "0.0.13",
44
"description": "SDK for hypercerts protocol",
55
"repository": "[email protected]:Network-Goods/hypercerts-sdk.git",
66
"author": "Network Goods",
@@ -36,7 +36,11 @@
3636
"@graphql-mesh/utils": "latest",
3737
"@graphql-tools/merge": "latest",
3838
"@network-goods/hypercerts-protocol": "0.0.6",
39+
"@plasmicapp/cli": "^0.1.196",
40+
"@plasmicapp/host": "^1.0.94",
41+
"@plasmicapp/react-web": "^0.2.141",
3942
"@types/jest": "^29.2.5",
43+
"@types/react": "^18.0.27",
4044
"ajv": "^8.11.2",
4145
"axios": "^1.2.2",
4246
"ethers": "^5.7.2",
@@ -46,6 +50,7 @@
4650
"loglevel": "^1.8.1",
4751
"mime": "^3.0.0",
4852
"nft.storage": "^7.0.0",
53+
"react": "^18.2.0",
4954
"ts-jest": "^29.0.3",
5055
"ts-mocha": "^10.0.0"
5156
},
@@ -54,6 +59,7 @@
5459
"@types/chai": "^4.3.4",
5560
"@types/node": "^18.11.17",
5661
"chai": "^4.3.7",
62+
"copyfiles": "^2.4.1",
5763
"it-all": "^2.0.0",
5864
"json-schema-to-typescript": "^11.0.2",
5965
"mockipfs": "^0.3.0",
@@ -75,7 +81,9 @@
7581
"graph:build:esm": "rm -rf ./src/.graphclient && NODE_OPTIONS='--loader ts-node/esm' graphclient build --filetype js --throwOnInvalidConfig && mv .graphclient ./src/.graphclient",
7682
"clean": "rm -rf ./lib && rm -rf ./src/types",
7783
"build": "yarn clean && yarn types:json && yarn graph:build:esm && yarn build:esm",
78-
"build:esm": "tsc",
84+
"build:esm": "tsc && yarn copy:css",
85+
"copy:css": "copyfiles --error -u 1 \"./src/**/*.css\" \"./lib/\"",
86+
"plasmic:sync": "plasmic sync",
7987
"prebuild": "yarn clean",
8088
"prepack": "yarn build",
8189
"test": "NODE_OPTIONS=\"--experimental-vm-modules\" jest",

plasmic.json

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
"platform": "react",
3+
"code": {
4+
"lang": "ts",
5+
"scheme": "blackbox",
6+
"reactRuntime": "classic"
7+
},
8+
"style": {
9+
"scheme": "css-modules",
10+
"defaultStyleCssFilePath": "plasmic/plasmic__default_style.module.css"
11+
},
12+
"images": {
13+
"scheme": "inlined",
14+
"publicDir": "../public",
15+
"publicUrlPrefix": "/static/"
16+
},
17+
"tokens": {
18+
"scheme": "theo",
19+
"tokensFilePath": "plasmic-tokens.theo.json"
20+
},
21+
"srcDir": "src/components",
22+
"defaultPlasmicDir": "./plasmic",
23+
"projects": [
24+
{
25+
"projectId": "tKtnZiEMup1PmF99tS3Jhx",
26+
"projectApiToken": "AsobqMlbpUFpzh4uM8U3j9T66AY1nPrX6jtk0JNeiVriaf0X50gR1cwuY8b1y1JLUSBF74oHrmo2KRMA07w",
27+
"projectName": "Hypercerts Core",
28+
"version": "latest",
29+
"cssFilePath": "plasmic/hypercerts_core/plasmic_hypercerts_core.module.css",
30+
"components": [
31+
{
32+
"id": "nRgxc3-mhP",
33+
"name": "HypercertImage",
34+
"type": "managed",
35+
"projectId": "tKtnZiEMup1PmF99tS3Jhx",
36+
"renderModuleFilePath": "plasmic/hypercerts_core/PlasmicHypercertImage.tsx",
37+
"importSpec": {
38+
"modulePath": "HypercertImage.tsx"
39+
},
40+
"cssFilePath": "plasmic/hypercerts_core/PlasmicHypercertImage.module.css",
41+
"scheme": "blackbox",
42+
"componentType": "component"
43+
},
44+
{
45+
"id": "Nv7cSj-s9F",
46+
"name": "WorkScopeChip",
47+
"type": "managed",
48+
"projectId": "tKtnZiEMup1PmF99tS3Jhx",
49+
"renderModuleFilePath": "plasmic/hypercerts_core/PlasmicWorkScopeChip.tsx",
50+
"importSpec": {
51+
"modulePath": "WorkScopeChip.tsx"
52+
},
53+
"cssFilePath": "plasmic/hypercerts_core/PlasmicWorkScopeChip.module.css",
54+
"scheme": "blackbox",
55+
"componentType": "component"
56+
}
57+
],
58+
"icons": [],
59+
"images": [
60+
{
61+
"id": "vr4pSW2pH",
62+
"name": "orb",
63+
"filePath": "plasmic/hypercerts_core/images/orb.png"
64+
},
65+
{
66+
"id": "bQIat_8lS",
67+
"name": "collection-logo",
68+
"filePath": "plasmic/hypercerts_core/images/collectionLogo.png"
69+
},
70+
{
71+
"id": "2etckvHUL",
72+
"name": "squiggly",
73+
"filePath": "plasmic/hypercerts_core/images/squiggly.png"
74+
},
75+
{
76+
"id": "_TBH9MuFK",
77+
"name": "tile-background",
78+
"filePath": "plasmic/hypercerts_core/images/tileBackground.png"
79+
}
80+
],
81+
"indirect": false,
82+
"globalContextsFilePath": "",
83+
"codeComponents": [
84+
{
85+
"id": "2LeErUoxBv",
86+
"name": "PlasmicHead",
87+
"componentImportPath": "@plasmicapp/react-web"
88+
},
89+
{
90+
"id": "XPYFyglhLZ",
91+
"name": "Fetcher",
92+
"componentImportPath": "@plasmicapp/react-web/lib/data-sources"
93+
}
94+
]
95+
}
96+
],
97+
"globalVariants": {
98+
"variantGroups": [
99+
{
100+
"id": "OGoErvQynxLNx",
101+
"name": "Screen",
102+
"projectId": "tKtnZiEMup1PmF99tS3Jhx",
103+
"contextFilePath": "plasmic/hypercerts_core/PlasmicGlobalVariant__Screen.tsx"
104+
}
105+
]
106+
},
107+
"wrapPagesWithGlobalContexts": true,
108+
"cliVersion": "0.1.196",
109+
"$schema": "https://unpkg.com/@plasmicapp/[email protected]/dist/plasmic.schema.json"
110+
}

plasmic.lock

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"projects": [
3+
{
4+
"projectId": "tKtnZiEMup1PmF99tS3Jhx",
5+
"version": "latest",
6+
"dependencies": {},
7+
"lang": "ts",
8+
"fileLocks": [
9+
{
10+
"type": "globalVariant",
11+
"assetId": "OGoErvQynxLNx",
12+
"checksum": "02cb7c0c3ff7f83bb388c5e90f0aa379"
13+
},
14+
{
15+
"type": "renderModule",
16+
"assetId": "nRgxc3-mhP",
17+
"checksum": "e9469d670f3ff0836181c0f6a51b0a2b"
18+
},
19+
{
20+
"type": "cssRules",
21+
"assetId": "nRgxc3-mhP",
22+
"checksum": "e9469d670f3ff0836181c0f6a51b0a2b"
23+
},
24+
{
25+
"type": "renderModule",
26+
"assetId": "Nv7cSj-s9F",
27+
"checksum": "696c22592d0a748f052194b3c0e39025"
28+
},
29+
{
30+
"type": "cssRules",
31+
"assetId": "Nv7cSj-s9F",
32+
"checksum": "696c22592d0a748f052194b3c0e39025"
33+
},
34+
{
35+
"type": "image",
36+
"assetId": "vr4pSW2pH",
37+
"checksum": "584f7c16d3d91b7ad19452166ccfcf33"
38+
},
39+
{
40+
"type": "image",
41+
"assetId": "bQIat_8lS",
42+
"checksum": "5f2b382edb73f907a81757aa07f153bd"
43+
},
44+
{
45+
"type": "image",
46+
"assetId": "2etckvHUL",
47+
"checksum": "2425352e5c64b289d65c6f7b2f2b1f0a"
48+
},
49+
{
50+
"type": "image",
51+
"assetId": "_TBH9MuFK",
52+
"checksum": "b590f3f90a32ddb3b31333c17189d9b7"
53+
},
54+
{
55+
"assetId": "tKtnZiEMup1PmF99tS3Jhx",
56+
"type": "projectCss",
57+
"checksum": "19940b6b9dfd706f089e6e1d13abb0c9"
58+
}
59+
],
60+
"codegenVersion": "0.0.1"
61+
}
62+
],
63+
"cliVersion": "0.1.196"
64+
}

src/components/HypercertImage.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import * as React from "react";
2+
import { PlasmicHypercertImage, DefaultHypercertImageProps } from "./plasmic/hypercerts_core/PlasmicHypercertImage";
3+
import { HTMLElementRefOf } from "@plasmicapp/react-web";
4+
import { HypercertMetadata } from "../types/metadata";
5+
6+
export interface HypercertImageProps extends DefaultHypercertImageProps {
7+
metadata: HypercertMetadata
8+
rootRef?: React.Ref<HTMLDivElement>;
9+
projectLogo?: React.ReactNode;
10+
collectionLogo?: React.ReactNode;
11+
percentOwnership?: number;
12+
}
13+
14+
function HypercertImage_(props: HypercertImageProps, ref: HTMLElementRefOf<"div">) {
15+
const { metadata, rootRef, projectLogo, collectionLogo, percentOwnership, ...rest } = props;
16+
17+
// This assumes we are using the schema in https://github.com/Network-Goods/hypercerts/issues/98
18+
const hideFraction = !percentOwnership;
19+
const impactScopeLabel = metadata.properties.impact_scope?.display_value;
20+
const workPeriodLabel = metadata.properties.work_timeframe?.display_value;
21+
const workScopes = metadata.properties.work_scope?.value;
22+
23+
// Validate and retrieve the proper workscope
24+
const getWorkScope = (i: number) =>
25+
Array.isArray(workScopes) && workScopes.length > i ?
26+
workScopes[i] :
27+
null;
28+
// get the props to pass into the WorkScopeChip component
29+
const getWorkScopeProps = (i: number) => {
30+
const label = getWorkScope(i);
31+
return {
32+
// Hide the chip if `null`
33+
style: label ? {} : { display: "none" },
34+
children: label,
35+
};
36+
};
37+
38+
return (
39+
<PlasmicHypercertImage
40+
root={{ ref }}
41+
{...rest}
42+
root2={{ ref:rootRef }}
43+
title={metadata.name}
44+
impactScope={impactScopeLabel}
45+
workPeriod={workPeriodLabel}
46+
projectLogo={projectLogo}
47+
hideCollectionLogo={true}
48+
collectionLogo={collectionLogo}
49+
workScope0={getWorkScopeProps(0)}
50+
workScope1={getWorkScopeProps(1)}
51+
workScope2={getWorkScopeProps(2)}
52+
hideFraction={hideFraction}
53+
percentOwnership={percentOwnership}
54+
/>
55+
);
56+
}
57+
58+
export const HypercertImage = React.forwardRef(HypercertImage_);

src/components/WorkScopeChip.tsx

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// This is a skeleton starter React component generated by Plasmic.
2+
// This file is owned by you, feel free to edit as you see fit.
3+
import * as React from "react";
4+
import { PlasmicWorkScopeChip, DefaultWorkScopeChipProps } from "./plasmic/hypercerts_core/PlasmicWorkScopeChip";
5+
import { HTMLElementRefOf } from "@plasmicapp/react-web";
6+
7+
// Your component props start with props for variants and slots you defined
8+
// in Plasmic, but you can add more here, like event handlers that you can
9+
// attach to named nodes in your component.
10+
//
11+
// If you don't want to expose certain variants or slots as a prop, you can use
12+
// Omit to hide them:
13+
//
14+
// interface WorkScopeChipProps extends Omit<DefaultWorkScopeChipProps, "hideProps1"|"hideProp2"> {
15+
// // etc.
16+
// }
17+
//
18+
// You can also stop extending from DefaultWorkScopeChipProps altogether and have
19+
// total control over the props for your component.
20+
export interface WorkScopeChipProps extends DefaultWorkScopeChipProps {}
21+
22+
function WorkScopeChip_(props: WorkScopeChipProps, ref: HTMLElementRefOf<"div">) {
23+
// Use PlasmicWorkScopeChip to render this component as it was
24+
// designed in Plasmic, by activating the appropriate variants,
25+
// attaching the appropriate event handlers, etc. You
26+
// can also install whatever React hooks you need here to manage state or
27+
// fetch data.
28+
//
29+
// Props you can pass into PlasmicWorkScopeChip are:
30+
// 1. Variants you want to activate,
31+
// 2. Contents for slots you want to fill,
32+
// 3. Overrides for any named node in the component to attach behavior and data,
33+
// 4. Props to set on the root node.
34+
//
35+
// By default, we are just piping all WorkScopeChipProps here, but feel free
36+
// to do whatever works for you.
37+
38+
return <PlasmicWorkScopeChip root={{ ref }} {...props} />;
39+
}
40+
41+
const WorkScopeChip = React.forwardRef(WorkScopeChip_);
42+
export default WorkScopeChip;

0 commit comments

Comments
 (0)