Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/near/neardevhub-widgets int…
Browse files Browse the repository at this point in the history
…o develop
  • Loading branch information
elliotBraem committed Nov 1, 2023
2 parents 80dad0c + 4b0b770 commit 3d87d13
Show file tree
Hide file tree
Showing 22 changed files with 1,273 additions and 264 deletions.
17 changes: 12 additions & 5 deletions docs/how-we-work.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,15 @@ Note: We expect you to complete your ticket within the number of days you commit

Notes: We may reassign issues that are not in progress yet. So it is important to indicate once you start working on it.

### 3. **Implement tests**

### 3. **Update Tickets**
1. As part of every development work, there should be tests that cover the functionality you have made, or the bug you have fixed
2. Implement tests to ensure that other developers will be warned if they break your code by accident
3. Also use tests to speed up your own development workflow. Writing tests during implementation should reduce the code-test iteration loop time.
4. Help the Pull Request reviewer, your tests should clearly describe what you have implemented. The better the test coverage, the better are the chances of getting your PR approved.
5. For more information about writing tests look into the [contribution guidelines](https://github.com/near/neardevhub-widgets/blob/main/CONTRIBUTING.md#writing-tests)

### 4. **Update Tickets**

1. If your ticket blocked:
1. Identify blocker: Add a comment specifying the blocker, what actions you have already taken to understand and mitigate the problem, and tag the appropriate people and specify what you need. Move the ticket to the blocked column.
Expand All @@ -98,24 +105,24 @@ Notes: We may reassign issues that are not in progress yet. So it is important t
c. Add a daily comment to the ticket to indicate your progress.


### 4. **Request Review**
### 5. **Request Review**

1. Deploy a preview version, see how to deploy a preview version below. Once you completed your work, and provide the link in the PR description.
2. Test the preview version to ensure everything works and meets the acceptance criteria
3. Change the PR from draft to “ready for review”

### 5. **Review**
### 6. **Review**

1. Another team member should review your work within one day. If you do not get a response, escalate on our Telegram channel.
2. For reviewers: If there are no reviews by the end of your work day, please leave your review.
3. We require one code owner review, and in the case the reviewer has questions about the UI/UX, a review from the PM, to approve the pull request.

### 6. **Address Review**
### 7. **Address Review**
1. Address any new review comments within 2 business days
2. Respond to each comment by either following the suggestion or providing a rationale for disagreement.
3. Request further review from the same reviewer.

### 7. **Completion**
### 8. **Completion**

1. If the PR is approved, a DevHub Tech Lead squash and merge the PR and the issue is considered done.
2. Move the issue to the “Done” column in our project board
Expand Down
2 changes: 1 addition & 1 deletion playwright-tests/tests/addons.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ test.describe("Wallet is connected", () => {
test("Addons configuration section comes up on load", async ({ page }) => {
await page.goto(baseUrl);

const addonsConfiguratorSelector = 'span:has-text("Addons")';
const addonsConfiguratorSelector = 'span:has-text("Add-Ons")';

await page.waitForSelector(addonsConfiguratorSelector, {
state: "visible",
Expand Down
9 changes: 9 additions & 0 deletions src/app.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,15 @@ function Page() {
/>
);
}
// ?page=blog
case "blog": {
return (
<Widget
src={"${REPL_DEVHUB}/widget/devhub.page.blog"}
props={passProps}
/>
);
}
default: {
// TODO: 404 page
return <p>404</p>;
Expand Down
16 changes: 8 additions & 8 deletions src/core/adapter/devhub-contract.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -129,14 +129,14 @@ function getAvailableAddons() {
// configurator_widget:
// "${REPL_DEVHUB}/widget/devhub.entity.addon.kanban.Configurator",
// },
// {
// id: "blog",
// title: "Blog",
// description: "Create a blog for your community",
// view_widget: "${REPL_DEVHUB}/widget/devhub.entity.addon.blog.Viewer",
// configurator_widget:
// "${REPL_DEVHUB}/widget/devhub.entity.addon.blog.Configurator",
// },
{
id: "blog",
title: "Blog",
description: "Create a blog for your community",
view_widget: "${REPL_DEVHUB}/widget/devhub.entity.addon.blog.Viewer",
configurator_widget:
"${REPL_DEVHUB}/widget/devhub.entity.addon.blog.Configurator",
},
];
// return Near.view("${REPL_DEVHUB_CONTRACT}", "get_available_addons") ?? null;
}
Expand Down
104 changes: 104 additions & 0 deletions src/devhub/components/molecule/Input.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
const TextInput = ({
className,
format,
inputProps: { className: inputClassName, ...inputProps },
key,
label,
multiline,
onChange,
placeholder,
type,
value,
skipPaddingGap,
style,
...otherProps
}) => {
const typeAttribute =
type === "text" ||
type === "password" ||
type === "number" ||
type === "date"
? type
: "text";

const renderedLabels = [
(label?.length ?? 0) > 0 ? (
<span className="d-inline-flex gap-1 text-wrap">
<span>{label}</span>

{inputProps.required ? <span className="text-danger">*</span> : null}
</span>
) : null,

format === "markdown" ? (
<i class="bi bi-markdown text-muted" title="Markdown" />
) : null,

format === "comma-separated" ? (
<span
className="d-inline-flex align-items-center text-muted"
style={{ fontSize: 12 }}
>
{format}
</span>
) : null,

(inputProps.max ?? null) !== null ? (
<span className="d-inline-flex text-muted" style={{ fontSize: 12 }}>{`${
value?.length ?? 0
} / ${inputProps.max}`}</span>
) : null,
].filter((label) => label !== null);

return (
<div
className={[
"d-flex flex-column flex-1 align-items-start justify-content-evenly",
skipPaddingGap ? "" : "gap-1 p-2",
className ?? "",
].join(" ")}
style={style}
{...otherProps}
>
{renderedLabels.length > 0 ? (
<span
className="d-flex justify-content-between align-items-center gap-3 w-100"
id={key}
>
{renderedLabels.map((label) => label)}
</span>
) : null}

{!multiline ? (
<div className="input-group">
{inputProps.prefix && (
<span className="input-group-text">{inputProps.prefix}</span>
)}
<input
aria-describedby={key}
aria-label={label}
className={["form-control border border-2", inputClassName].join(
" "
)}
type={typeAttribute}
{...{ onChange, placeholder, value, ...inputProps }}
/>
</div>
) : (
<textarea
aria-describedby={key}
aria-label={label}
className={["form-control border border-2", inputClassName].join(" ")}
placeholder={
placeholder + (inputProps.required ? " ( required )" : "")
}
style={{ resize: inputProps.resize ?? "vertical" }}
type={typeAttribute}
{...{ onChange, placeholder, value, ...inputProps }}
/>
)}
</div>
);
};

return TextInput(props);
192 changes: 156 additions & 36 deletions src/devhub/entity/addon/blog/Card.jsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,158 @@
const { title, content, author, image, community, tags } = props;

const cidToURL = (cid) => `https://ipfs.near.social/ipfs/${cid}`;

return (
<div className="card" style={{ width: "18rem" }}>
{image && (
<img
src={cidToURL(image.cid)}
className="card-img-top"
alt="Blog image"
/>
)}

<div className="card-body">
<h5 className="card-title">{title}</h5>

<p className="card-text">
<small className="text-muted">Author: {author || "AUTHOR"}</small>
</p>

<div>
{(tags || []).map((tag) => (
<Widget
src="${REPL_DEVHUB}/widget/devhub.components.atom.Tag"
props={{ tag }}
/>
))}
</div>

<p className="card-text mt-2">Community: {community || "COMMUNITY"}</p>

<Link to="#" className="btn btn-primary mt-2">
Read More
</Link>
</div>
</div>
);
const Container = styled.div`
width: 100%;
height: 100%;
padding: 24px;
background: #fffefe;
border-radius: 16px;
overflow: hidden;
border: 1px rgba(129, 129, 129, 0.3) solid;
display: inline-flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
gap: 24px;
`;

const InfoContainer = styled.div`
padding-right: 16px;
display: inline-flex;
justify-content: flex-start;
align-items: center;
gap: 16px;
`;

const InfoText = styled.div`
color: ${(props) => props.color || "#818181"};
font-size: 16px;
font-family: ${(props) => props.fontFamily || "Aeonik Fono"};
font-weight: ${(props) => props.fontWeight || "400"};
line-height: 20px;
word-wrap: break-word;
`;

const TitleContainer = styled.div`
width: 344px;
padding-right: 16px;
display: inline-flex;
justify-content: flex-start;
align-items: center;
gap: 8px;
`;

const Title = styled.div`
width: 422px;
color: #151515;
font-size: 36px;
font-family: "Aeonik";
font-weight: 700;
line-height: 39.6px;
word-wrap: break-word;
`;

const DescriptionContainer = styled.div`
align-self: stretch;
height: 155px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
`;

const Description = styled.div`
align-self: stretch;
height: 103px;
padding-bottom: 16px;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 16px;
`;

const DescriptionText = styled.div`
align-self: stretch;
color: #151515;
font-size: 24px;
font-family: "Aeonik";
font-weight: 400;
line-height: 28.8px;
word-wrap: break-word;
`;

const TagsContainer = styled.div`
padding: 16px;
border-radius: 360px;
overflow: hidden;
display: inline-flex;
justify-content: flex-start;
align-items: center;
gap: 16px;
`;

const Separator = styled.div`
color: #8a8e93;
font-size: 16px;
font-family: "Circular Std";
font-weight: 400;
line-height: 19.2px;
word-wrap: break-word;
`;

function Card({ labels, data }) {
const {
title,
subtitle,
description,
category,
author,
image,
community,
date,
} = data;

function formatDate(date) {
const options = {
weekday: "short",
year: "numeric",
month: "short",
day: "numeric",
hour: "2-digit",
minute: "2-digit",
second: "2-digit",
timeZoneName: "short",
};
return date.toLocaleString("en-US", options).replace(",", "");
}

return (
<Container>
<InfoContainer>
<InfoText color="#F40303" fontWeight="700">
{category && category.toUpperCase()}
</InfoText>
<Separator>·</Separator>
<InfoText>{date && formatDate(date)}</InfoText>
</InfoContainer>
<TitleContainer>
<Title>{title}</Title>
</TitleContainer>
<DescriptionContainer>
<Description>
<DescriptionText>{description}</DescriptionText>
</Description>
<TagsContainer>
{(labels || []).map((label, index) => (
<div key={label}>
{index > 0 && <Separator />}
<InfoText fontWeight="700">{label}</InfoText>
</div>
))}
</TagsContainer>
</DescriptionContainer>
</Container>
);
}

return { Card };
Loading

0 comments on commit 3d87d13

Please sign in to comment.