Skip to content

Add fundable projects page #239

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,13 @@ const config: Config = {
className: "custom_navbar_item",
label: "Blog",
position: "left",
},
{
to: "/fundable/",
className: "custom_navbar_item",
label: "Fundable projects",
position: "right",
className:"fundable_projects"
},
{
to: "/contact/",
Expand Down
10 changes: 10 additions & 0 deletions src/components/footer/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,16 @@ export default function Footer() {
</li>
</ul>
</div>
<div className="col flex-horizontally-centered">
<ul>
<li>
<Link href={"/fundable"}>Fundable projects</Link>
</li>
<li>
<Link href={"/contact"}>Contact us</Link>
</li>
</ul>
</div>
</div>
</div>
</div>
Expand Down
29 changes: 29 additions & 0 deletions src/components/fundable/LargeProjectCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import styles from "./styles.module.css";
import React from "react";

export default function LargeProjectCard({ project }) {
return (
<div className={styles.large_project_card}>
<div className={"container"}>
<div className={"row padding-none"}>
<div className="col col--12 col--offset-1">
<div className={styles.large_card_project_category}>
{project.category}
</div>
<div className={styles.large_card_project_title}>{project.title}</div>
</div>
</div>
<div className="row">
<div className="col col--10 col--offset-1">
<div className={styles.large_project_card_text_container}></div>
<div className={styles.large_project_card_section_title}>Overview</div>
<div className={styles.large_project_card_text}>
<project.description />
</div>
</div>
</div>

</div>
</div>
);
}
80 changes: 80 additions & 0 deletions src/components/fundable/LargeProjectCardPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useHistory, useLocation } from "@docusaurus/router";
import { useEffect } from "react";
import styles from "./styles.module.css";
import LargeProjectCard from "./LargeProjectCard";
import { getCategoryFromProjectTitle } from ".";
import FundableProjects from ".";
import Layout from "@theme/Layout";
import { Route } from 'react-router-dom';


export default function LargeProjectCardPage() {
const location = useLocation();
const history = useHistory();

useEffect(() => {
if (location.state?.fromFundable) {
window.scrollTo({ top: location.state.scrollY ?? 0, behavior: 'auto' });
}
}, []);

const handleOverlayClick = () => {
const scrollY = location.state?.scrollY;
setTimeout(() => {
if (scrollY !== undefined) {
window.scrollTo({ top: scrollY, behavior: 'auto' });
}
}, 0);
history.replace('/fundable');
};

const handleClose = () => {
const scrollY = location.state?.scrollY;
if (location.state?.fromFundable) {
history.replace('/fundable');

setTimeout(() => {
if (scrollY !== undefined) {
window.scrollTo({ top: scrollY, behavior: 'auto' });
}
}, 0);
} else {
history.goBack();
}
}
return (
<Layout>
<FundableProjects />
<Route
path="/fundable/:shortTitle"
render={({ match }) => {
const { shortTitle } = match.params; /* extract the dynamic part from the url i.e. the shortTitle*/
const projectsByCategory = getCategoryFromProjectTitle(shortTitle);
console.log('projectsByCategory:', projectsByCategory);
const project = projectsByCategory.find((project) => project.shortTitle.replace(/\s+/g, '') === shortTitle);
if (!project) return null;

return (
<div className={styles.modal_overlay} onClick={handleOverlayClick}>
<div
className={styles.modal_content}
onClick={(e) => e.stopPropagation()}
>
<button
className="close-button"
style={{
position: "absolute",
top: "10px",
right: "10px",
}}
onClick={handleClose}
/>
<LargeProjectCard project={project} />
</div>
</div>
);
}}
/>
</Layout>
)
}
26 changes: 26 additions & 0 deletions src/components/fundable/MenuSideBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// src/components/CustomSidebar.js
import React from 'react';
import { useLocation } from '@docusaurus/router';


const menuItems = [
{ label: 'Overview', path: '/fundable' },
{ label: 'Eligibility', path: '/fundable/eligibility' },
{ label: 'Apply', path: '/fundable/apply' },
];

export default function MenuSidebar() {
const location = useLocation();

return (
<nav className="custom-sidebar">
<ul>
{menuItems.map(item => (
<li key={item.path} className={location.pathname === item.path ? 'active' : ''}>
<Link to={item.path}>{item.label}</Link>
</li>
))}
</ul>
</nav>
);
}
25 changes: 25 additions & 0 deletions src/components/fundable/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from "react";

export default function ProgressBar({ value = 0, color = '#4caf50' }) {
return (

<div style={{
background: '#eee',
borderRadius: '4px',
border: 'solid 0.5px',
height: '10px',
width: '100px',
margin: '10px 0'
}}>

<div style={{
width: `${value}%`,
background: color,
border: 'solid 0.5px',
height: '100%',
borderRadius: '4px',
transition: 'width 0.3s ease-in-out',
}} />
</div>
);
}
22 changes: 22 additions & 0 deletions src/components/fundable/ProjectCategory.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import styles from "./styles.module.css";
import { SmallProjectCard } from "./SmallProjectCard";


export default function ProjectCategory({ projectCategoryName, projectCategory }) {
return (
<div className={styles.project_category_container}>
<h2 className={styles.category_header}> {projectCategoryName}</h2>
<div className={"container"}>
<ul className="row padding-none row-with-margin-top">
{projectCategory.map((project) => (
<li className="cards-list" key={project.category}>
<div className="col" style={{justifyContent: "left"}}>
<SmallProjectCard project={project} />
</div>
</li>
))}
</ul>
</div>
</div>
);
}
61 changes: 61 additions & 0 deletions src/components/fundable/SmallProjectCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import styles from "./styles.module.css";
import ProgressBar from "./ProgressBar";
import { useHistory } from "@docusaurus/router";

export function SmallProjectCard({ project }) {
const history = useHistory();

function openDialog() {
const shortTitle = project.shortTitle.replace(/\s+/g, '');

history.push({
pathname: `/fundable/${shortTitle}`,
state: { fromFundable: true, scrollY: window.scrollY, },
});
}


return (
<div onClick={openDialog}>
<div className={"card" + " " + styles.fundable_project_card}>
<div className="card__header">
<div
className={styles.project_title
}
>
{project.title}
</div>
</div>
<div className="card__body">
<div style={{display: "flex"}}>
<div>
<div
className={styles.project_catch_up_phrase}
>
{project.catchUpPhrase}

</div>
<div style={{ fontSize: "14px" }}>
Indicative Price: {project.price} €
</div>

<div style={{ fontSize: "14px" }}>
Shareable between {project.maxNbOfFunders} funders.
</div>
<div style={{ fontSize: "14px" }}>
Currently this project is supported by {project.currentNbOfFunders} funders.
</div>
<div style={{ fontSize: "14px" }}>
Financed at {project.currentFundingPercentage} %
</div>
<div>
<ProgressBar value={project.currentFundingPercentage} color={'var(--ifm-color-primary-p1'}/>
</div>
</div>
</div>
</div>
</div>

</div>
)
}
1 change: 1 addition & 0 deletions src/components/fundable/descriptions/MambaNewFeature.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
To be writen.
5 changes: 5 additions & 0 deletions src/components/fundable/descriptions/ModernizeNbconvert.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Conversion of Jupyter notebooks to PDF currently relies on nbconvert in the backend, which in turns uses a headless browser for producing the PDF. We propose to directly perform the PDF conversion in the user's browser, which will simplify the architecture and make it function with JupyterLite.

Nbconvert heavily relies on Jinja2 templates for conversion to different formats.

We will utilize a JavaScript implementation of Jinja2 covering the required features of Jinja to produce a frontend version of nbconvert that does not require Python but still provides a good coverage of the nbconvert features, including the use of custom templates.
42 changes: 42 additions & 0 deletions src/components/fundable/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import styles from "./styles.module.css";
import { fundableProjectsDetails } from "./projectsDetails";
import ProjectCategory from "./ProjectCategory";

export function getCategoryFromProjectTitle(title: string) {
for (const [categoryName, projectsByCategory] of Object.entries(fundableProjectsDetails)) {
const project = projectsByCategory.find((project) => project.shortTitle.replace(/\s+/g, '').replace(/\s+/g, '') === title);
if (project) {
return projectsByCategory;
}
}
return null;
}

export default function FundableProjects() {
return (
<div className="main-container-with-margins">
<div className="container upper-container-with-margin-top">
<div className="row">
<div className="col col--10">
<h1 style={{ padding: "0" }}>Check out our projects available for funding!</h1>
</div>
</div>
<div className="row">
<div className="col">
<ProjectCategory
projectCategoryName={"Jupyter Ecosystem"}
projectCategory={fundableProjectsDetails.jupyterEcosystem}
/>
<ProjectCategory
projectCategoryName={"Package Management"}
projectCategory={fundableProjectsDetails.packageManagement}
/>

</div>
</div>
</div>
</div>


);
}
42 changes: 42 additions & 0 deletions src/components/fundable/projectsDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import ModernizeNbconvertMD from "@site/src/components/fundable/descriptions/ModernizeNbconvert.md"
import MambaNewFeatureMD from "@site/src/components/fundable/descriptions/MambaNewFeature.md"

export const fundableProjectsDetails = {
jupyterEcosystem: [
{
category: "Jupyter Ecosystem",
title: "Modernize nbconvert",
shortTitle: "Modern Nbconvert",
catchUpPhrase: "HELP US TO MODERNIZE NBCONVERT",
description: ModernizeNbconvertMD,
optionA: "This is option A",
optionB: "This is option B",
customOption: "This is custom option",
icons: [],
price: 15000,
maxNbOfFunders: 3,
currentNbOfFunders: 2,
currentFundingPercentage: 65,
note: "Note: Costs and features can be further adapted following discussion with the funding organization. Open-source under relevant licenses. The funding organization will be credited in communication about the project.",
repoLink: "https://github.com/jupyter/nbconvert"
}],
packageManagement: [
{
category: "Package Management",
title: "New feature",
shortTitle: "New Feature",
catchUpPhrase: "WE PROPOSE A NEW FEATURE",
description: MambaNewFeatureMD,
optionA: "This is option A",
optionB: "This is option B",
customOption: "This is custom option",
icons: [],
price: 25000,
maxNbOfFunders: 3,
currentNbOfFunders: 1,
currentFundingPercentage: 33,
note: "Note: Costs and features can be further adapted following discussion with the funding organization. Open-source under relevant licenses. The funding organization will be credited in communication about the project.",
repoLink: "https://github.com/mamba-org/mamba"
}],
}

Loading