Skip to content

Commit

Permalink
refactor: working communities with new root
Browse files Browse the repository at this point in the history
  • Loading branch information
elliotBraem committed Oct 14, 2023
1 parent 1ce1a2d commit 5b0efc9
Show file tree
Hide file tree
Showing 7 changed files with 309 additions and 137 deletions.
56 changes: 56 additions & 0 deletions src/DevHub/entity/community/Activity.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
const {
nearDevGovGigsWidgetsAccountId,
nearDevGovGigsContractAccountId,
handle,
} = props;

const { getCommunity } = VM.require(
`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.modules.contract-sdk`
);

const communityData = getCommunity(nearDevGovGigsContractAccountId, { handle });

if (communityData === null) {
return <div>Loading...</div>;
}

return (
<div class="row">
<div class="col-md-9">
<div class="d-flex align-items-center justify-content-between mb-2">
<small class="text-muted">
<span>Required tags:</span>
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/gigs-board.components.atom.tag`}
props={{
linkTo: "Feed",
...communityData,
}}
/>
</small>
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.components.molecule.PostControls`}
props={{ labels: communityData.tag }}
/>
</div>
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.entity.post.List`}
props={{
nearDevGovGigsContractAccountId,
nearDevGovGigsWidgetsAccountId,
tag: communityData.tag,
}}
/>
</div>
<div class="col-md-3 container-fluid">
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/gigs-board.entity.community.sidebar`}
props={{
nearDevGovGigsContractAccountId,
nearDevGovGigsWidgetsAccountId,
handle: communityData.handle,
}}
/>
</div>
</div>
);
51 changes: 33 additions & 18 deletions src/DevHub/entity/community/BrandingConfigurator.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,32 +76,47 @@ const cidToURL = (cid) => `https://ipfs.near.social/ipfs/${cid}`;

const { data, onSubmit, hasConfigurePermissions, link } = props;

State.init({
banner: { cid: data.banner_url.split("/").at(-1) },
logo: { cid: data.logo_url.split("/").at(-1) },
})

// const [banner, setBanner] = useState(data.banner_url.split("/").at(-1));
// const [logo, setLogo] = useState(data.logo_url.split("/").at(-1));

useEffect(() => {
// console.log(state.banner);
onSubmit({
banner_url: cidToURL(state.banner.cid),
logo_url: cidToURL(state.logo.cid),
const initialInput = { banner: null, logo: null };

const initialValues = {
banner: { cid: data.banner_url.split("/").at(-1) },
logo: { cid: data.logo_url.split("/").at(-1) },
};

State.init({
input: initialInput,
});
}, [state.logo, state.banner]);

const hasUnsubmittedChanges = Object.values(state.input).some(
(value) => value !== null
);

const isSynced = state.input === initialValues;

if (hasUnsubmittedChanges && !isSynced) {
onSubmit({
banner_url: cidToURL(state.input.banner?.cid ?? initialValues.banner.cid),
logo_url: cidToURL(state.input.logo?.cid ?? initialValues.logo.cid),
});

State.update((lastKnownState) => ({
...lastKnownState,
input: initialInput,
}));
}

return (
<div style={{ height: 280 }}>
<Banner
alt="Community banner preview"
className="card-img-top d-flex flex-column justify-content-end align-items-end p-4"
style={{
background: `center / cover no-repeat url(${cidToURL(state.banner.cid)})`,
background: `center / cover no-repeat url(${cidToURL(
initialValues.banner.cid
)})`,
}}
>
{hasConfigurePermissions && <IpfsImageUpload image={state.banner.cid} />}
{hasConfigurePermissions && <IpfsImageUpload image={state.input.banner} />}
</Banner>
<Logo
alt="Community logo preview"
Expand All @@ -114,10 +129,10 @@ return (
width: 128,
height: 128,

background: `center / cover no-repeat url(${cidToURL(state.logo.cid)})`,
background: `center / cover no-repeat url(${cidToURL(initialValues.logo.cid)})`,
}}
>
{hasConfigurePermissions && <IpfsImageUpload image={state.logo.cid} />}
{hasConfigurePermissions && <IpfsImageUpload image={state.input.logo} />}
</Logo>

<div
Expand Down
67 changes: 67 additions & 0 deletions src/DevHub/entity/community/Teams.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
const {
nearDevGovGigsWidgetsAccountId,
nearDevGovGigsContractAccountId,
handle,
} = props;

const { getCommunity } = VM.require(
`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.modules.contract-sdk`
);

const communityData = getCommunity(nearDevGovGigsContractAccountId, { handle });

if (communityData === null) {
return <div>Loading...</div>;
}

const UserList = ({ name, users }) => (
<div>
{(users ?? []).map((user, i) => (
<div className={`row ${i < users.length - 1 ? "mb-3" : ""}`}>
<div class="col-3">
<b>{name + " #" + (i + 1)}</b>
</div>

<div class="col-9">
<span
key={user}
className="d-inline-flex"
style={{ fontWeight: 500 }}
>
<Widget
src="mob.near/widget/ProfileLine"
props={{ accountId: user, hideAccountId: true, tooltip: true }}
/>
</span>
</div>
</div>
))}
</div>
);

return (
<div
className="d-flex flex-column align-items-center gap-4 w-100"
>
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.components.molecule.Tile`}
props={{
className: "p-3 w-100",
style: { "maxWidth": 960 },
children: (
<div>
<div
className="d-flex align-items-center justify-content-between w-100 pb-3"
style={{ minHeight: 30 }}
>
<h5 className="h5 d-inline-flex gap-2 m-0">
<span>Admins</span>
</h5>
</div>
<UserList name="Admin" users={communityData.admins} />
</div>
),
}}
/>
</div>
);
13 changes: 12 additions & 1 deletion src/DevHub/modules/Struct.jsx → src/DevHub/modules/utils.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,15 @@ const Struct = {
input !== null && typeof input === "object" && !Array.isArray(input),
};

return { Struct };
function href({ gateway, widgetSrc, params }) {
params = Object.entries(params)
.filter(([_key, nullable]) => (nullable ?? null) !== null)
.map(([key, value]) => `${key}=${value}`)
.join("&");

return `${gateway ? `https://${gateway}` : ""}/${widgetSrc}/${
params ? `?${params}` : ""
}`;
}

return { href, Struct };
81 changes: 45 additions & 36 deletions src/DevHub/pages/Communities.jsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
const {
nearDevGovGigsWidgetsAccountId,
nearDevGovGigsContractAccountId,
createCommunity,
} = props;
const { nearDevGovGigsWidgetsAccountId, nearDevGovGigsContractAccountId } =
props;

const { getAllCommunitiesMetadata } = VM.require(
const { getAllCommunitiesMetadata, createCommunity } = VM.require(
`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.modules.contract-sdk`
);

if (!getAllCommunitiesMetadata) {
if (!getAllCommunitiesMetadata || !createCommunity) {
return <p>Loading modules...</p>;
}

const { Struct } = VM.require(
`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.modules.Struct`
`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.modules.utils`
);

if (!Struct) {
return <p>Loading modules...</p>;
}

const CommunityInputsDefaults = {
State.init({
handle: "",
name: "",
tag: "",
description: "",
};
});

const CommunityInputsPartialSchema = {
handle: {
Expand Down Expand Up @@ -114,20 +111,31 @@ const [showSpawner, setShowSpawner] = useState(false);

const CommunitySpawner = () => (
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/gigs-board.components.organism.configurator`}
src={`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.components.molecule.Tile`}
props={{
heading: "Community information",
externalState: CommunityInputsDefaults,
fullWidth: true,
isActive: true,
isHidden,
isUnlocked: true,
isValid: communityInputsValidator,
onSubmit: onCommunitySubmit,
schema: CommunityInputsPartialSchema,
submitIcon: { type: "bootstrap_icon", variant: "bi-rocket-takeoff-fill" },
submitLabel: "Launch",
onCancel: () => setShowSpawner(false),
className: "p-3",
children: (
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.components.organism.Configurator`}
props={{
heading: "Community information",
externalState: CommunityInputsDefaults,
fullWidth: true,
isActive: true,
isUnlocked: true,
isValid: communityInputsValidator,
onSubmit: onCommunitySubmit,
schema: CommunityInputsPartialSchema,
submitIcon: {
type: "bootstrap_icon",
variant: "bi-rocket-takeoff-fill",
},
submitLabel: "Launch",
onCancel: () => setShowSpawner(false),
nearDevGovGigsWidgetsAccountId,
}}
/>
),
}}
/>
);
Expand Down Expand Up @@ -248,19 +256,20 @@ return (
Discover NEAR developer communities
</p>
</div>

<div className="d-flex flex-column justify-content-center">
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.components.molecule.Button`}
props={{
icon: { type: "bootstrap_icon", variant: "bi-people-fill" },
onClick: () => setShowSpawner(!showSpawner),
className: "btn btn-primary",
label: "Create Community",
nearDevGovGigsWidgetsAccountId,
}}
/>
</div>
{context.accountId && (
<div className="d-flex flex-column justify-content-center">
<Widget
src={`${nearDevGovGigsWidgetsAccountId}/widget/DevHub.components.molecule.Button`}
props={{
icon: { type: "bootstrap_icon", variant: "bi-people-fill" },
onClick: () => setShowSpawner(!showSpawner),
className: "btn btn-primary",
label: "Create Community",
nearDevGovGigsWidgetsAccountId,
}}
/>
</div>
)}
</div>
{/* // TODO: Align centers */}
<div className="d-flex flex-wrap align-content-start gap-4 p-4 w-100 h-100">
Expand Down
Loading

0 comments on commit 5b0efc9

Please sign in to comment.